Full AST support and better Sema support for C++ try-catch.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61346 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 079ed4e..586e8f9 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -350,6 +350,18 @@
 }
 
 void CXXCatchStmt::Destroy(ASTContext& C) {
-  ExceptionDecl->Destroy(C);
+  if (ExceptionDecl)
+    ExceptionDecl->Destroy(C);
   Stmt::Destroy(C);
 }
+
+// CXXTryStmt
+Stmt::child_iterator CXXTryStmt::child_begin() { return &Stmts[0]; }
+Stmt::child_iterator CXXTryStmt::child_end() { return &Stmts[0]+Stmts.size(); }
+
+CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
+                       Stmt **handlers, unsigned numHandlers)
+  : Stmt(CXXTryStmtClass), TryLoc(tryLoc) {
+  Stmts.push_back(tryBlock);
+  Stmts.insert(Stmts.end(), handlers, handlers + numHandlers);
+}
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 61cd89f..5214789 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -52,6 +52,7 @@
     void PrintRawDecl(Decl *D);
     void PrintRawDeclStmt(DeclStmt *S);
     void PrintRawIfStmt(IfStmt *If);
+    void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
     
     void PrintExpr(Expr *E) {
       if (E)
@@ -474,14 +475,29 @@
   OS << "\n";
 }
 
-void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
-  Indent() << "catch (";
+void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
+  OS << "catch (";
   if (Decl *ExDecl = Node->getExceptionDecl())
     PrintRawDecl(ExDecl);
   else
     OS << "...";
   OS << ") ";
   PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
+}
+
+void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
+  Indent();
+  PrintRawCXXCatchStmt(Node);
+  OS << "\n";
+}
+
+void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
+  Indent() << "try ";
+  PrintRawCompoundStmt(Node->getTryBlock());
+  for(unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
+    OS << " ";
+    PrintRawCXXCatchStmt(Node->getHandler(i));
+  }
   OS << "\n";
 }
 
diff --git a/lib/AST/StmtSerialization.cpp b/lib/AST/StmtSerialization.cpp
index 2d6f755..a6c95b9 100644
--- a/lib/AST/StmtSerialization.cpp
+++ b/lib/AST/StmtSerialization.cpp
@@ -1540,3 +1540,19 @@
   Stmt *HandlerBlock = D.ReadOwnedPtr<Stmt>(C);
   return new CXXCatchStmt(CatchLoc, ExDecl, HandlerBlock);
 }
+
+void CXXTryStmt::EmitImpl(llvm::Serializer& S) const {
+  S.Emit(TryLoc);
+  S.EmitInt(Stmts.size());
+  S.BatchEmitOwnedPtrs(Stmts.size(), &Stmts[0]);
+}
+
+CXXTryStmt *
+CXXTryStmt::CreateImpl(llvm::Deserializer& D, ASTContext& C) {
+  SourceLocation TryLoc = SourceLocation::ReadVal(D);
+  unsigned size = D.ReadInt();
+  llvm::SmallVector<Stmt*, 4> Stmts(size);
+  D.BatchReadOwnedPtrs<Stmt>(size, &Stmts[0], C);
+
+  return new CXXTryStmt(TryLoc, Stmts[0], &Stmts[1], size - 1);
+}