diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 864c73f..baf4ce4 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -74,6 +74,7 @@
        CGM =Mod;
        FunctionName = name;
        Function = 0;
+       ArgTys.clear();
        va_list Args;
        va_start(Args, RetTy);
          while (const llvm::Type *ArgTy = va_arg(Args, const llvm::Type*))
@@ -88,12 +89,15 @@
     */
    operator llvm::Function*() {
      if (!Function) {
-       assert(0 != CGM && "Using an uninitialized LazyRuntimeFunction!");
+       if (0 == FunctionName) return 0;
+       // We put the return type on the end of the vector, so pop it back off
        const llvm::Type *RetTy = ArgTys.back();
        ArgTys.pop_back();
        llvm::FunctionType *FTy = llvm::FunctionType::get(RetTy, ArgTys, false);
        Function =
          cast<llvm::Function>(CGM->CreateRuntimeFunction(FTy, FunctionName));
+       // We won't need to use the types again, so we may as well clean up the
+       // vector now
        ArgTys.resize(0);
      }
      return Function;
@@ -128,26 +132,64 @@
   const llvm::Type *BoolTy;
   /// Metadata kind used to tie method lookups to message sends.
   unsigned msgSendMDKind;
-  llvm::Constant *MakeConstantString(const std::string &Str, const std::string
+  llvm::Constant *MakeConstantString(const std::string &Str,
+                                     const std::string &Name="") {
+    llvm::Constant *ConstStr = CGM.GetAddrOfConstantCString(Str, Name.c_str());
+    return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2);
+  }
+  llvm::Constant *ExportUniqueString(const std::string &Str,
+                                     const std::string prefix) {
+    std::string name = prefix + Str;
+    llvm::Constant *ConstStr = TheModule.getGlobalVariable(name);
+    if (!ConstStr) {
+      llvm::Constant *value = llvm::ConstantArray::get(VMContext, Str, true);
+      ConstStr = new llvm::GlobalVariable(TheModule, value->getType(), true,
+              llvm::GlobalValue::LinkOnceODRLinkage, value, prefix + Str);
+    }
+    return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2);
+  }
 
-      &Name="");
-  llvm::Constant *ExportUniqueString(const std::string &Str, const std::string
-          prefix);
   llvm::GlobalVariable *MakeGlobal(const llvm::StructType *Ty,
-    std::vector<llvm::Constant*> &V, llvm::StringRef Name="",
-    llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage);
+                                   std::vector<llvm::Constant*> &V,
+                                   llvm::StringRef Name="",
+                                   llvm::GlobalValue::LinkageTypes linkage
+                                         =llvm::GlobalValue::InternalLinkage) {
+    llvm::Constant *C = llvm::ConstantStruct::get(Ty, V);
+    return new llvm::GlobalVariable(TheModule, Ty, false,
+        linkage, C, Name);
+  }
+
   llvm::GlobalVariable *MakeGlobal(const llvm::ArrayType *Ty,
-    std::vector<llvm::Constant*> &V, llvm::StringRef Name="",
-    llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage);
+                                   std::vector<llvm::Constant*> &V,
+                                   llvm::StringRef Name="",
+                                   llvm::GlobalValue::LinkageTypes linkage
+                                         =llvm::GlobalValue::InternalLinkage) {
+    llvm::Constant *C = llvm::ConstantArray::get(Ty, V);
+    return new llvm::GlobalVariable(TheModule, Ty, false,
+                                    linkage, C, Name);
+  }
   llvm::GlobalVariable *MakeGlobalArray(const llvm::Type *Ty,
-    std::vector<llvm::Constant*> &V, llvm::StringRef Name="",
-    llvm::GlobalValue::LinkageTypes linkage=llvm::GlobalValue::InternalLinkage);
+                                        std::vector<llvm::Constant*> &V,
+                                        llvm::StringRef Name="",
+                                        llvm::GlobalValue::LinkageTypes linkage
+                                         =llvm::GlobalValue::InternalLinkage) {
+    llvm::ArrayType *ArrayTy = llvm::ArrayType::get(Ty, V.size());
+    return MakeGlobal(ArrayTy, V, Name, linkage);
+  }
+  /**
+   * Ensures that the value has the required type, by inserting a bitcast if
+   * required.  This function lets us avoid inserting bitcasts that are
+   * redundant.
+   */
   llvm::Value* EnforceType(CGBuilderTy B, llvm::Value *V, const llvm::Type *Ty){
     if (V->getType() == Ty) return V;
     return B.CreateBitCast(V, Ty);
   }
   // Some zeros used for GEPs in lots of places.
   llvm::Constant *Zeros[2];
+  /**
+   * Null pointer value.  Mainly used as a terminator in various arrays.
+   */
   llvm::Constant *NULLPtr;
   llvm::LLVMContext &VMContext;
 private:
@@ -180,10 +222,16 @@
   LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn, 
     WeakAssignFn, GlobalAssignFn;
 
+protected:
   LazyRuntimeFunction ExceptionThrowFn;
+  LazyRuntimeFunction ExceptionReThrowFn;
+  LazyRuntimeFunction EnterCatchFn;
+  LazyRuntimeFunction ExitCatchFn;
   LazyRuntimeFunction SyncEnterFn;
   LazyRuntimeFunction SyncExitFn;
 
+private:
+
   LazyRuntimeFunction EnumerationMutationFn;
   LazyRuntimeFunction GetPropertyFn;
   LazyRuntimeFunction SetPropertyFn;
@@ -237,7 +285,6 @@
   llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
       const ObjCIvarDecl *Ivar);
   void EmitClassRef(const std::string &className);
-  void EmitObjCXXTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S);
 protected:
   virtual llvm::Value *LookupIMP(CodeGenFunction &CGF,
                                  llvm::Value *&Receiver,
@@ -463,6 +510,16 @@
       // Slot_t objc_msg_lookup_super(struct objc_super*, SEL);
       SlotLookupSuperFn.init(&CGM, "objc_slot_lookup_super", SlotTy,
               PtrToObjCSuperTy, SelectorTy, NULL);
+      // If we're in ObjC++ mode, then we want to make 
+      if (CGM.getLangOptions().CPlusPlus) {
+        const llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
+        // void *__cxa_begin_catch(void *e)
+        EnterCatchFn.init(&CGM, "__cxa_begin_catch", PtrTy, PtrTy, NULL);
+        // void __cxa_end_catch(void)
+        EnterCatchFn.init(&CGM, "__cxa_end_catch", VoidTy, NULL);
+        // void _Unwind_Resume_or_Rethrow(void*)
+        EnterCatchFn.init(&CGM, "_Unwind_Resume_or_Rethrow", VoidTy, PtrTy, NULL);
+      }
     }
 };
 
@@ -551,6 +608,7 @@
 
   // void objc_exception_throw(id);
   ExceptionThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy, NULL);
+  ExceptionReThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy, NULL);
   // int objc_sync_enter(id);
   SyncEnterFn.init(&CGM, "objc_sync_enter", IntTy, IdTy, NULL);
   // int objc_sync_exit(id);
@@ -580,6 +638,7 @@
   IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
               true));
 
+  // Don't bother initialising the GC stuff unless we're compiling in GC mode
   if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
     // Get selectors needed in GC mode
     RetainSel = GetNullarySelector("retain", CGM.getContext());
@@ -671,6 +730,29 @@
 }
 
 llvm::Constant *CGObjCGNU::GetEHType(QualType T) {
+  if (!CGM.getLangOptions().CPlusPlus) {
+      if (T->isObjCIdType()
+          || T->isObjCQualifiedIdType()) {
+        // With the old ABI, there was only one kind of catchall, which broke
+        // foreign exceptions.  With the new ABI, we use __objc_id_typeinfo as
+        // a pointer indicating object catchalls, and NULL to indicate real
+        // catchalls
+        if (CGM.getLangOptions().ObjCNonFragileABI) {
+          return MakeConstantString("@id");
+        } else {
+          return 0;
+        }
+      }
+
+      // All other types should be Objective-C interface pointer types.
+      const ObjCObjectPointerType *OPT =
+        T->getAs<ObjCObjectPointerType>();
+      assert(OPT && "Invalid @catch type.");
+      const ObjCInterfaceDecl *IDecl =
+        OPT->getObjectType()->getInterface();
+      assert(IDecl && "Invalid @catch type.");
+      return MakeConstantString(IDecl->getIdentifier()->getName());
+  }
   // For Objective-C++, we want to provide the ability to catch both C++ and
   // Objective-C objects in the same function.
 
@@ -729,44 +811,6 @@
   return llvm::ConstantExpr::getBitCast(TI, PtrToInt8Ty);
 }
 
-llvm::Constant *CGObjCGNU::MakeConstantString(const std::string &Str,
-                                              const std::string &Name) {
-  llvm::Constant *ConstStr = CGM.GetAddrOfConstantCString(Str, Name.c_str());
-  return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2);
-}
-llvm::Constant *CGObjCGNU::ExportUniqueString(const std::string &Str,
-        const std::string prefix) {
-  std::string name = prefix + Str;
-  llvm::Constant *ConstStr = TheModule.getGlobalVariable(name);
-  if (!ConstStr) {
-    llvm::Constant *value = llvm::ConstantArray::get(VMContext, Str, true);
-    ConstStr = new llvm::GlobalVariable(TheModule, value->getType(), true,
-            llvm::GlobalValue::LinkOnceODRLinkage, value, prefix + Str);
-  }
-  return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2);
-}
-
-llvm::GlobalVariable *CGObjCGNU::MakeGlobal(const llvm::StructType *Ty,
-    std::vector<llvm::Constant*> &V, llvm::StringRef Name,
-    llvm::GlobalValue::LinkageTypes linkage) {
-  llvm::Constant *C = llvm::ConstantStruct::get(Ty, V);
-  return new llvm::GlobalVariable(TheModule, Ty, false,
-      linkage, C, Name);
-}
-
-llvm::GlobalVariable *CGObjCGNU::MakeGlobal(const llvm::ArrayType *Ty,
-    std::vector<llvm::Constant*> &V, llvm::StringRef Name,
-    llvm::GlobalValue::LinkageTypes linkage) {
-  llvm::Constant *C = llvm::ConstantArray::get(Ty, V);
-  return new llvm::GlobalVariable(TheModule, Ty, false,
-                                  linkage, C, Name);
-}
-llvm::GlobalVariable *CGObjCGNU::MakeGlobalArray(const llvm::Type *Ty,
-  std::vector<llvm::Constant*> &V, llvm::StringRef Name,
-  llvm::GlobalValue::LinkageTypes linkage) {
-  llvm::ArrayType *ArrayTy = llvm::ArrayType::get(Ty, V.size());
-  return MakeGlobal(ArrayTy, V, Name, linkage);
-}
 /// Generate an NSConstantString object.
 llvm::Constant *CGObjCGNU::GenerateConstantString(const StringLiteral *SL) {
 
@@ -2073,180 +2117,11 @@
   return EnumerationMutationFn;
 }
 
-namespace {
-  struct CallSyncExit : EHScopeStack::Cleanup {
-    llvm::Value *SyncExitFn;
-    llvm::Value *SyncArg;
-    CallSyncExit(llvm::Value *SyncExitFn, llvm::Value *SyncArg)
-      : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
-
-    void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
-      CGF.Builder.CreateCall(SyncExitFn, SyncArg)->setDoesNotThrow();
-    }
-  };
-}
-
 void CGObjCGNU::EmitSynchronizedStmt(CodeGenFunction &CGF,
                                      const ObjCAtSynchronizedStmt &S) {
-  // Evaluate the lock operand.  This should dominate the cleanup.
-  llvm::Value *SyncArg =
-    CGF.EmitScalarExpr(S.getSynchExpr());
-
-  // Acquire the lock.
-  SyncArg = CGF.Builder.CreateBitCast(SyncArg, IdTy);
-  CGF.Builder.CreateCall(SyncEnterFn, SyncArg);
-
-  // Register an all-paths cleanup to release the lock.
-  CGF.EHStack.pushCleanup<CallSyncExit>(NormalAndEHCleanup, SyncExitFn,
-      SyncArg);
-
-  // Emit the body of the statement.
-  CGF.EmitStmt(S.getSynchBody());
-
-  // Pop the lock-release cleanup.
-  CGF.PopCleanupBlock();
+  EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
 }
 
-namespace {
-  struct CatchHandler {
-    const VarDecl *Variable;
-    const Stmt *Body;
-    llvm::BasicBlock *Block;
-    llvm::Value *TypeInfo;
-  };
-
-  struct CallObjCEndCatch : EHScopeStack::Cleanup {
-    CallObjCEndCatch(bool MightThrow, llvm::Value *Fn) :
-      MightThrow(MightThrow), Fn(Fn) {}
-    bool MightThrow;
-    llvm::Value *Fn;
-
-    void Emit(CodeGenFunction &CGF, bool IsForEH) {
-      if (!MightThrow) {
-        CGF.Builder.CreateCall(Fn)->setDoesNotThrow();
-        return;
-      }
-
-      CGF.EmitCallOrInvoke(Fn, 0, 0);
-    }
-  };
-}
-
-void CGObjCGNU::EmitObjCXXTryStmt(CodeGenFunction &CGF,
-                                  const ObjCAtTryStmt &S) {
-  std::vector<const llvm::Type*> Args(1, PtrToInt8Ty);
-  llvm::FunctionType *FTy = llvm::FunctionType::get(PtrToInt8Ty, Args, false);
-  const llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
-
-  llvm::Constant *beginCatchFn =
-    CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch");
-
-  FTy = llvm::FunctionType::get(VoidTy, false);
-  llvm::Constant *endCatchFn =
-    CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch");
-  FTy = llvm::FunctionType::get(VoidTy, Args, false);
-  llvm::Constant *exceptionRethrowFn =
-    CGM.CreateRuntimeFunction(FTy, "_Unwind_Resume_or_Rethrow");
-
-  // Jump destination for falling out of catch bodies.
-  CodeGenFunction::JumpDest Cont;
-  if (S.getNumCatchStmts())
-    Cont = CGF.getJumpDestInCurrentScope("eh.cont");
-
-  CodeGenFunction::FinallyInfo FinallyInfo;
-  if (const ObjCAtFinallyStmt *Finally = S.getFinallyStmt())
-    FinallyInfo = CGF.EnterFinallyBlock(Finally->getFinallyBody(),
-                                        beginCatchFn,
-                                        endCatchFn,
-                                        exceptionRethrowFn);
-
-  llvm::SmallVector<CatchHandler, 8> Handlers;
-
-  // Enter the catch, if there is one.
-  if (S.getNumCatchStmts()) {
-    for (unsigned I = 0, N = S.getNumCatchStmts(); I != N; ++I) {
-      const ObjCAtCatchStmt *CatchStmt = S.getCatchStmt(I);
-      const VarDecl *CatchDecl = CatchStmt->getCatchParamDecl();
-
-      Handlers.push_back(CatchHandler());
-      CatchHandler &Handler = Handlers.back();
-      Handler.Variable = CatchDecl;
-      Handler.Body = CatchStmt->getCatchBody();
-      Handler.Block = CGF.createBasicBlock("catch");
-
-      // @catch(...) always matches.
-      if (!CatchDecl) {
-        Handler.TypeInfo = 0; // catch-all
-        // Don't consider any other catches.
-        break;
-      }
-
-      Handler.TypeInfo = GetEHType(CatchDecl->getType());
-    }
-
-    EHCatchScope *Catch = CGF.EHStack.pushCatch(Handlers.size());
-    for (unsigned I = 0, E = Handlers.size(); I != E; ++I)
-      Catch->setHandler(I, Handlers[I].TypeInfo, Handlers[I].Block);
-  }
-  
-  // Emit the try body.
-  CGF.EmitStmt(S.getTryBody());
-
-  // Leave the try.
-  if (S.getNumCatchStmts())
-    CGF.EHStack.popCatch();
-
-  // Remember where we were.
-  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
-
-  // Emit the handlers.
-  for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
-    CatchHandler &Handler = Handlers[I];
-
-    CGF.EmitBlock(Handler.Block);
-    llvm::Value *RawExn = CGF.Builder.CreateLoad(CGF.getExceptionSlot());
-
-    // Enter the catch.
-    llvm::CallInst *Exn =
-      CGF.Builder.CreateCall(beginCatchFn, RawExn,
-                             "exn.adjusted");
-    Exn->setDoesNotThrow();
-
-    // Add a cleanup to leave the catch.
-    bool EndCatchMightThrow = (Handler.Variable == 0);
-    CGF.EHStack.pushCleanup<CallObjCEndCatch>(NormalAndEHCleanup,
-                                              EndCatchMightThrow,
-                                              endCatchFn);
-
-    // Bind the catch parameter if it exists.
-    if (const VarDecl *CatchParam = Handler.Variable) {
-      const llvm::Type *CatchType = CGF.ConvertType(CatchParam->getType());
-      llvm::Value *CastExn = CGF.Builder.CreateBitCast(Exn, CatchType);
-
-      CGF.EmitAutoVarDecl(*CatchParam);
-      CGF.Builder.CreateStore(CastExn, CGF.GetAddrOfLocalVar(CatchParam));
-    }
-
-    CGF.ObjCEHValueStack.push_back(Exn);
-    CGF.EmitStmt(Handler.Body);
-    CGF.ObjCEHValueStack.pop_back();
-
-    // Leave the earlier cleanup.
-    CGF.PopCleanupBlock();
-
-    CGF.EmitBranchThroughCleanup(Cont);
-  }  
-
-  // Go back to the try-statement fallthrough.
-  CGF.Builder.restoreIP(SavedIP);
-
-  // Pop out of the normal cleanup on the finally.
-  if (S.getFinallyStmt())
-    CGF.ExitFinallyBlock(FinallyInfo);
-
-  if (Cont.isValid())
-    CGF.EmitBlock(Cont.getBlock());
-}
 
 void CGObjCGNU::EmitTryStmt(CodeGenFunction &CGF,
                             const ObjCAtTryStmt &S) {
@@ -2258,127 +2133,11 @@
   // catch handlers with calls to __blah_begin_catch/__blah_end_catch
   // (or even _Unwind_DeleteException), but probably doesn't
   // interoperate very well with foreign exceptions.
-
+  //
   // In Objective-C++ mode, we actually emit something equivalent to the C++
-  // exception handler.
-  if (CGM.getLangOptions().CPlusPlus) {
-    EmitObjCXXTryStmt(CGF, S);
-    return;
-  }
-
-  // Jump destination for falling out of catch bodies.
-  CodeGenFunction::JumpDest Cont;
-  if (S.getNumCatchStmts())
-    Cont = CGF.getJumpDestInCurrentScope("eh.cont");
-
-  // We handle @finally statements by pushing them as a cleanup
-  // before entering the catch.
-  CodeGenFunction::FinallyInfo FinallyInfo;
-  if (const ObjCAtFinallyStmt *Finally = S.getFinallyStmt()) {
-    FinallyInfo = CGF.EnterFinallyBlock(Finally->getFinallyBody(), 0, 0,
-                                        ExceptionThrowFn);
-  }
-
-  llvm::SmallVector<CatchHandler, 8> Handlers;
-
-  // Enter the catch, if there is one.
-  if (S.getNumCatchStmts()) {
-    for (unsigned I = 0, N = S.getNumCatchStmts(); I != N; ++I) {
-      const ObjCAtCatchStmt *CatchStmt = S.getCatchStmt(I);
-      const VarDecl *CatchDecl = CatchStmt->getCatchParamDecl();
-
-      Handlers.push_back(CatchHandler());
-      CatchHandler &Handler = Handlers.back();
-      Handler.Variable = CatchDecl;
-      Handler.Body = CatchStmt->getCatchBody();
-      Handler.Block = CGF.createBasicBlock("catch");
-
-      // @catch() and @catch(id) both catch any ObjC exception.
-      // Treat them as catch-alls.
-      // really be catching foreign exceptions?
-      
-      if (!CatchDecl) {
-        Handler.TypeInfo = 0; // catch-all
-        // Don't consider any other catches.
-        break;
-      }
-      if (CatchDecl->getType()->isObjCIdType()
-          || CatchDecl->getType()->isObjCQualifiedIdType()) {
-        // With the old ABI, there was only one kind of catchall, which broke
-        // foreign exceptions.  With the new ABI, we use __objc_id_typeinfo as
-        // a pointer indicating object catchalls, and NULL to indicate real
-        // catchalls
-        if (CGM.getLangOptions().ObjCNonFragileABI) {
-          Handler.TypeInfo = MakeConstantString("@id");
-          continue;
-        } else {
-          Handler.TypeInfo = 0; // catch-all
-          // Don't consider any other catches.
-          break;
-        }
-      }
-
-      // All other types should be Objective-C interface pointer types.
-      const ObjCObjectPointerType *OPT =
-        CatchDecl->getType()->getAs<ObjCObjectPointerType>();
-      assert(OPT && "Invalid @catch type.");
-      const ObjCInterfaceDecl *IDecl =
-        OPT->getObjectType()->getInterface();
-      assert(IDecl && "Invalid @catch type.");
-      Handler.TypeInfo = MakeConstantString(IDecl->getNameAsString());
-    }
-
-    EHCatchScope *Catch = CGF.EHStack.pushCatch(Handlers.size());
-    for (unsigned I = 0, E = Handlers.size(); I != E; ++I)
-      Catch->setHandler(I, Handlers[I].TypeInfo, Handlers[I].Block);
-  }
-  
-  // Emit the try body.
-  CGF.EmitStmt(S.getTryBody());
-
-  // Leave the try.
-  if (S.getNumCatchStmts())
-    CGF.EHStack.popCatch();
-
-  // Remember where we were.
-  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
-
-  // Emit the handlers.
-  for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
-    CatchHandler &Handler = Handlers[I];
-    CGF.EmitBlock(Handler.Block);
-
-    llvm::Value *Exn = CGF.Builder.CreateLoad(CGF.getExceptionSlot());
-
-    // Bind the catch parameter if it exists.
-    if (const VarDecl *CatchParam = Handler.Variable) {
-      const llvm::Type *CatchType = CGF.ConvertType(CatchParam->getType());
-      Exn = CGF.Builder.CreateBitCast(Exn, CatchType);
-
-      CGF.EmitAutoVarDecl(*CatchParam);
-      CGF.Builder.CreateStore(Exn, CGF.GetAddrOfLocalVar(CatchParam));
-    }
-
-    CGF.ObjCEHValueStack.push_back(Exn);
-    CGF.EmitStmt(Handler.Body);
-    CGF.ObjCEHValueStack.pop_back();
-
-    CGF.EmitBranchThroughCleanup(Cont);
-  }  
-
-  // Go back to the try-statement fallthrough.
-  CGF.Builder.restoreIP(SavedIP);
-
-  // Pop out of the finally.
-  if (S.getFinallyStmt())
-    CGF.ExitFinallyBlock(FinallyInfo);
-
-  if (Cont.isValid()) {
-    if (Cont.getBlock()->use_empty())
-      delete Cont.getBlock();
-    else
-      CGF.EmitBlock(Cont.getBlock());
-  }
+  // exception handler. 
+  EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
+  return ;
 }
 
 void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF,
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index a4d95d4..dcc6d52 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -42,9 +42,6 @@
 using namespace clang;
 using namespace CodeGen;
 
-// Common CGObjCRuntime functions, these don't belong here, but they
-// don't belong in CGObjCRuntime either so we will live with it for
-// now.
 
 static void EmitNullReturnInitialization(CodeGenFunction &CGF,
                                          ReturnValueSlot &returnSlot,
@@ -55,112 +52,6 @@
   CGF.EmitNullInitialization(returnSlot.getValue(), resultType);
 }
 
-static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
-                                     const ObjCInterfaceDecl *OID,
-                                     const ObjCImplementationDecl *ID,
-                                     const ObjCIvarDecl *Ivar) {
-  const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
-
-  // FIXME: We should eliminate the need to have ObjCImplementationDecl passed
-  // in here; it should never be necessary because that should be the lexical
-  // decl context for the ivar.
-
-  // If we know have an implementation (and the ivar is in it) then
-  // look up in the implementation layout.
-  const ASTRecordLayout *RL;
-  if (ID && ID->getClassInterface() == Container)
-    RL = &CGM.getContext().getASTObjCImplementationLayout(ID);
-  else
-    RL = &CGM.getContext().getASTObjCInterfaceLayout(Container);
-
-  // Compute field index.
-  //
-  // FIXME: The index here is closely tied to how ASTContext::getObjCLayout is
-  // implemented. This should be fixed to get the information from the layout
-  // directly.
-  unsigned Index = 0;
-  llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
-  CGM.getContext().ShallowCollectObjCIvars(Container, Ivars);
-  for (unsigned k = 0, e = Ivars.size(); k != e; ++k) {
-    if (Ivar == Ivars[k])
-      break;
-    ++Index;
-  }
-  assert(Index != Ivars.size() && "Ivar is not inside container!");
-  assert(Index < RL->getFieldCount() && "Ivar is not inside record layout!");
-
-  return RL->getFieldOffset(Index);
-}
-
-uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
-                                              const ObjCInterfaceDecl *OID,
-                                              const ObjCIvarDecl *Ivar) {
-  return LookupFieldBitOffset(CGM, OID, 0, Ivar) / 8;
-}
-
-uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
-                                              const ObjCImplementationDecl *OID,
-                                              const ObjCIvarDecl *Ivar) {
-  return LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar) / 8;
-}
-
-LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
-                                               const ObjCInterfaceDecl *OID,
-                                               llvm::Value *BaseValue,
-                                               const ObjCIvarDecl *Ivar,
-                                               unsigned CVRQualifiers,
-                                               llvm::Value *Offset) {
-  // Compute (type*) ( (char *) BaseValue + Offset)
-  const llvm::Type *I8Ptr = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
-  QualType IvarTy = Ivar->getType();
-  const llvm::Type *LTy = CGF.CGM.getTypes().ConvertTypeForMem(IvarTy);
-  llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, I8Ptr);
-  V = CGF.Builder.CreateInBoundsGEP(V, Offset, "add.ptr");
-  V = CGF.Builder.CreateBitCast(V, llvm::PointerType::getUnqual(LTy));
-
-  if (!Ivar->isBitField()) {
-    LValue LV = CGF.MakeAddrLValue(V, IvarTy);
-    LV.getQuals().addCVRQualifiers(CVRQualifiers);
-    return LV;
-  }
-
-  // We need to compute an access strategy for this bit-field. We are given the
-  // offset to the first byte in the bit-field, the sub-byte offset is taken
-  // from the original layout. We reuse the normal bit-field access strategy by
-  // treating this as an access to a struct where the bit-field is in byte 0,
-  // and adjust the containing type size as appropriate.
-  //
-  // FIXME: Note that currently we make a very conservative estimate of the
-  // alignment of the bit-field, because (a) it is not clear what guarantees the
-  // runtime makes us, and (b) we don't have a way to specify that the struct is
-  // at an alignment plus offset.
-  //
-  // Note, there is a subtle invariant here: we can only call this routine on
-  // non-synthesized ivars but we may be called for synthesized ivars.  However,
-  // a synthesized ivar can never be a bit-field, so this is safe.
-  const ASTRecordLayout &RL =
-    CGF.CGM.getContext().getASTObjCInterfaceLayout(OID);
-  uint64_t TypeSizeInBits = CGF.CGM.getContext().toBits(RL.getSize());
-  uint64_t FieldBitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar);
-  uint64_t BitOffset = FieldBitOffset % 8;
-  uint64_t ContainingTypeAlign = 8;
-  uint64_t ContainingTypeSize = TypeSizeInBits - (FieldBitOffset - BitOffset);
-  uint64_t BitFieldSize =
-    Ivar->getBitWidth()->EvaluateAsInt(CGF.getContext()).getZExtValue();
-
-  // Allocate a new CGBitFieldInfo object to describe this access.
-  //
-  // FIXME: This is incredibly wasteful, these should be uniqued or part of some
-  // layout object. However, this is blocked on other cleanups to the
-  // Objective-C code, so for now we just live with allocating a bunch of these
-  // objects.
-  CGBitFieldInfo *Info = new (CGF.CGM.getContext()) CGBitFieldInfo(
-    CGBitFieldInfo::MakeInfo(CGF.CGM.getTypes(), Ivar, BitOffset, BitFieldSize,
-                             ContainingTypeSize, ContainingTypeAlign));
-
-  return LValue::MakeBitfield(V, *Info,
-                              IvarTy.getCVRQualifiers() | CVRQualifiers);
-}
 
 ///
 
diff --git a/lib/CodeGen/CGObjCRuntime.cpp b/lib/CodeGen/CGObjCRuntime.cpp
new file mode 100644
index 0000000..49b1ce1
--- /dev/null
+++ b/lib/CodeGen/CGObjCRuntime.cpp
@@ -0,0 +1,308 @@
+//==- CGObjCRuntime.cpp - Interface to Shared Objective-C Runtime Features ==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This abstract class defines the interface for Objective-C runtime-specific
+// code generation.  It provides some concrete helper methods for functionality
+// shared between all (or most) of the Objective-C runtimes supported by clang.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGObjCRuntime.h"
+
+#include "CGRecordLayout.h"
+#include "CodeGenModule.h"
+#include "CodeGenFunction.h"
+#include "CGCleanup.h"
+
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/StmtObjC.h"
+
+#include "llvm/Support/CallSite.h"
+
+using namespace clang;
+using namespace CodeGen;
+
+static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
+                                     const ObjCInterfaceDecl *OID,
+                                     const ObjCImplementationDecl *ID,
+                                     const ObjCIvarDecl *Ivar) {
+  const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
+
+  // FIXME: We should eliminate the need to have ObjCImplementationDecl passed
+  // in here; it should never be necessary because that should be the lexical
+  // decl context for the ivar.
+
+  // If we know have an implementation (and the ivar is in it) then
+  // look up in the implementation layout.
+  const ASTRecordLayout *RL;
+  if (ID && ID->getClassInterface() == Container)
+    RL = &CGM.getContext().getASTObjCImplementationLayout(ID);
+  else
+    RL = &CGM.getContext().getASTObjCInterfaceLayout(Container);
+
+  // Compute field index.
+  //
+  // FIXME: The index here is closely tied to how ASTContext::getObjCLayout is
+  // implemented. This should be fixed to get the information from the layout
+  // directly.
+  unsigned Index = 0;
+  llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
+  CGM.getContext().ShallowCollectObjCIvars(Container, Ivars);
+  for (unsigned k = 0, e = Ivars.size(); k != e; ++k) {
+    if (Ivar == Ivars[k])
+      break;
+    ++Index;
+  }
+  assert(Index != Ivars.size() && "Ivar is not inside container!");
+  assert(Index < RL->getFieldCount() && "Ivar is not inside record layout!");
+
+  return RL->getFieldOffset(Index);
+}
+
+uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
+                                              const ObjCInterfaceDecl *OID,
+                                              const ObjCIvarDecl *Ivar) {
+  return LookupFieldBitOffset(CGM, OID, 0, Ivar) / 8;
+}
+
+uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
+                                              const ObjCImplementationDecl *OID,
+                                              const ObjCIvarDecl *Ivar) {
+  return LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar) / 8;
+}
+
+LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
+                                               const ObjCInterfaceDecl *OID,
+                                               llvm::Value *BaseValue,
+                                               const ObjCIvarDecl *Ivar,
+                                               unsigned CVRQualifiers,
+                                               llvm::Value *Offset) {
+  // Compute (type*) ( (char *) BaseValue + Offset)
+  const llvm::Type *I8Ptr = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+  QualType IvarTy = Ivar->getType();
+  const llvm::Type *LTy = CGF.CGM.getTypes().ConvertTypeForMem(IvarTy);
+  llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, I8Ptr);
+  V = CGF.Builder.CreateInBoundsGEP(V, Offset, "add.ptr");
+  V = CGF.Builder.CreateBitCast(V, llvm::PointerType::getUnqual(LTy));
+
+  if (!Ivar->isBitField()) {
+    LValue LV = CGF.MakeAddrLValue(V, IvarTy);
+    LV.getQuals().addCVRQualifiers(CVRQualifiers);
+    return LV;
+  }
+
+  // We need to compute an access strategy for this bit-field. We are given the
+  // offset to the first byte in the bit-field, the sub-byte offset is taken
+  // from the original layout. We reuse the normal bit-field access strategy by
+  // treating this as an access to a struct where the bit-field is in byte 0,
+  // and adjust the containing type size as appropriate.
+  //
+  // FIXME: Note that currently we make a very conservative estimate of the
+  // alignment of the bit-field, because (a) it is not clear what guarantees the
+  // runtime makes us, and (b) we don't have a way to specify that the struct is
+  // at an alignment plus offset.
+  //
+  // Note, there is a subtle invariant here: we can only call this routine on
+  // non-synthesized ivars but we may be called for synthesized ivars.  However,
+  // a synthesized ivar can never be a bit-field, so this is safe.
+  const ASTRecordLayout &RL =
+    CGF.CGM.getContext().getASTObjCInterfaceLayout(OID);
+  uint64_t TypeSizeInBits = CGF.CGM.getContext().toBits(RL.getSize());
+  uint64_t FieldBitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar);
+  uint64_t BitOffset = FieldBitOffset % 8;
+  uint64_t ContainingTypeAlign = 8;
+  uint64_t ContainingTypeSize = TypeSizeInBits - (FieldBitOffset - BitOffset);
+  uint64_t BitFieldSize =
+    Ivar->getBitWidth()->EvaluateAsInt(CGF.getContext()).getZExtValue();
+
+  // Allocate a new CGBitFieldInfo object to describe this access.
+  //
+  // FIXME: This is incredibly wasteful, these should be uniqued or part of some
+  // layout object. However, this is blocked on other cleanups to the
+  // Objective-C code, so for now we just live with allocating a bunch of these
+  // objects.
+  CGBitFieldInfo *Info = new (CGF.CGM.getContext()) CGBitFieldInfo(
+    CGBitFieldInfo::MakeInfo(CGF.CGM.getTypes(), Ivar, BitOffset, BitFieldSize,
+                             ContainingTypeSize, ContainingTypeAlign));
+
+  return LValue::MakeBitfield(V, *Info,
+                              IvarTy.getCVRQualifiers() | CVRQualifiers);
+}
+
+namespace {
+  struct CatchHandler {
+    const VarDecl *Variable;
+    const Stmt *Body;
+    llvm::BasicBlock *Block;
+    llvm::Value *TypeInfo;
+  };
+
+  struct CallObjCEndCatch : EHScopeStack::Cleanup {
+    CallObjCEndCatch(bool MightThrow, llvm::Value *Fn) :
+      MightThrow(MightThrow), Fn(Fn) {}
+    bool MightThrow;
+    llvm::Value *Fn;
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      if (!MightThrow) {
+        CGF.Builder.CreateCall(Fn)->setDoesNotThrow();
+        return;
+      }
+
+      CGF.EmitCallOrInvoke(Fn, 0, 0);
+    }
+  };
+}
+
+
+void CGObjCRuntime::EmitTryCatchStmt(CodeGenFunction &CGF,
+                                     const ObjCAtTryStmt &S,
+                                     llvm::Function *beginCatchFn,
+                                     llvm::Function *endCatchFn,
+                                     llvm::Function *exceptionRethrowFn) {
+  // Jump destination for falling out of catch bodies.
+  CodeGenFunction::JumpDest Cont;
+  if (S.getNumCatchStmts())
+    Cont = CGF.getJumpDestInCurrentScope("eh.cont");
+
+  CodeGenFunction::FinallyInfo FinallyInfo;
+  if (const ObjCAtFinallyStmt *Finally = S.getFinallyStmt())
+    FinallyInfo = CGF.EnterFinallyBlock(Finally->getFinallyBody(),
+                                        beginCatchFn,
+                                        endCatchFn,
+                                        exceptionRethrowFn);
+
+  llvm::SmallVector<CatchHandler, 8> Handlers;
+
+  // Enter the catch, if there is one.
+  if (S.getNumCatchStmts()) {
+    for (unsigned I = 0, N = S.getNumCatchStmts(); I != N; ++I) {
+      const ObjCAtCatchStmt *CatchStmt = S.getCatchStmt(I);
+      const VarDecl *CatchDecl = CatchStmt->getCatchParamDecl();
+
+      Handlers.push_back(CatchHandler());
+      CatchHandler &Handler = Handlers.back();
+      Handler.Variable = CatchDecl;
+      Handler.Body = CatchStmt->getCatchBody();
+      Handler.Block = CGF.createBasicBlock("catch");
+
+      // @catch(...) always matches.
+      if (!CatchDecl) {
+        Handler.TypeInfo = 0; // catch-all
+        // Don't consider any other catches.
+        break;
+      }
+
+      Handler.TypeInfo = GetEHType(CatchDecl->getType());
+    }
+
+    EHCatchScope *Catch = CGF.EHStack.pushCatch(Handlers.size());
+    for (unsigned I = 0, E = Handlers.size(); I != E; ++I)
+      Catch->setHandler(I, Handlers[I].TypeInfo, Handlers[I].Block);
+  }
+  
+  // Emit the try body.
+  CGF.EmitStmt(S.getTryBody());
+
+  // Leave the try.
+  if (S.getNumCatchStmts())
+    CGF.EHStack.popCatch();
+
+  // Remember where we were.
+  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
+
+  // Emit the handlers.
+  for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
+    CatchHandler &Handler = Handlers[I];
+
+    CGF.EmitBlock(Handler.Block);
+    llvm::Value *RawExn = CGF.Builder.CreateLoad(CGF.getExceptionSlot());
+
+    // Enter the catch.
+    llvm::Value *Exn = RawExn;
+    if (beginCatchFn) {
+      Exn = CGF.Builder.CreateCall(beginCatchFn, RawExn, "exn.adjusted");
+      cast<llvm::CallInst>(Exn)->setDoesNotThrow();
+    }
+
+    if (endCatchFn) {
+      // Add a cleanup to leave the catch.
+      bool EndCatchMightThrow = (Handler.Variable == 0);
+
+      CGF.EHStack.pushCleanup<CallObjCEndCatch>(NormalAndEHCleanup,
+                                                EndCatchMightThrow,
+                                                endCatchFn);
+    }
+
+    // Bind the catch parameter if it exists.
+    if (const VarDecl *CatchParam = Handler.Variable) {
+      const llvm::Type *CatchType = CGF.ConvertType(CatchParam->getType());
+      llvm::Value *CastExn = CGF.Builder.CreateBitCast(Exn, CatchType);
+
+      CGF.EmitAutoVarDecl(*CatchParam);
+      CGF.Builder.CreateStore(CastExn, CGF.GetAddrOfLocalVar(CatchParam));
+    }
+
+    CGF.ObjCEHValueStack.push_back(Exn);
+    CGF.EmitStmt(Handler.Body);
+    CGF.ObjCEHValueStack.pop_back();
+
+    // Leave the earlier cleanup.
+    if (endCatchFn) 
+      CGF.PopCleanupBlock();
+
+    CGF.EmitBranchThroughCleanup(Cont);
+  }  
+
+  // Go back to the try-statement fallthrough.
+  CGF.Builder.restoreIP(SavedIP);
+
+  // Pop out of the normal cleanup on the finally.
+  if (S.getFinallyStmt())
+    CGF.ExitFinallyBlock(FinallyInfo);
+
+  if (Cont.isValid())
+    CGF.EmitBlock(Cont.getBlock());
+}
+
+namespace {
+  struct CallSyncExit : EHScopeStack::Cleanup {
+    llvm::Value *SyncExitFn;
+    llvm::Value *SyncArg;
+    CallSyncExit(llvm::Value *SyncExitFn, llvm::Value *SyncArg)
+      : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
+
+    void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
+      CGF.Builder.CreateCall(SyncExitFn, SyncArg)->setDoesNotThrow();
+    }
+  };
+}
+
+void CGObjCRuntime::EmitAtSynchronizedStmt(CodeGenFunction &CGF,
+                                           const ObjCAtSynchronizedStmt &S,
+                                           llvm::Function *syncEnterFn,
+                                           llvm::Function *syncExitFn) {
+  // Evaluate the lock operand.  This should dominate the cleanup.
+  llvm::Value *SyncArg =
+    CGF.EmitScalarExpr(S.getSynchExpr());
+
+  // Acquire the lock.
+  SyncArg = CGF.Builder.CreateBitCast(SyncArg, syncEnterFn->getFunctionType()->getParamType(0));
+  CGF.Builder.CreateCall(syncEnterFn, SyncArg);
+
+  // Register an all-paths cleanup to release the lock.
+  CGF.EHStack.pushCleanup<CallSyncExit>(NormalAndEHCleanup, syncExitFn,
+      SyncArg);
+
+  // Emit the body of the statement.
+  CGF.EmitStmt(S.getSynchBody());
+
+  // Pop the lock-release cleanup.
+  CGF.PopCleanupBlock();
+}
diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h
index e6869ad..9778e18 100644
--- a/lib/CodeGen/CGObjCRuntime.h
+++ b/lib/CodeGen/CGObjCRuntime.h
@@ -87,6 +87,26 @@
                                   const ObjCIvarDecl *Ivar,
                                   unsigned CVRQualifiers,
                                   llvm::Value *Offset);
+  /// Emits a try / catch statement.  This function is intended to be called by
+  /// subclasses, and provides a generic mechanism for generating these, which
+  /// should be usable by all runtimes.  The caller must provide the functions to
+  /// call when entering and exiting a @catch() block, and the function used to
+  /// rethrow exceptions.  If the begin and end catch functions are NULL, then
+  /// the function assumes that the EH personality function provides the
+  /// thrown object directly.
+  void EmitTryCatchStmt(CodeGenFunction &CGF,
+                        const ObjCAtTryStmt &S,
+                        llvm::Function *beginCatchFn,
+                        llvm::Function *endCatchFn,
+                        llvm::Function *exceptionRethrowFn);
+  /// Emits an @synchronize() statement, using the syncEnterFn and syncExitFn
+  /// arguments as the functions called to lock and unlock the object.  This
+  /// function can be called by subclasses that use zero-cost exception
+  /// handling.
+  void EmitAtSynchronizedStmt(CodeGenFunction &CGF,
+                            const ObjCAtSynchronizedStmt &S,
+                            llvm::Function *syncEnterFn,
+                            llvm::Function *syncExitFn);
 
 public:
   virtual ~CGObjCRuntime();
