AST for objective-c's @throw statement and its pretty-printing.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43802 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/AST/Stmt.cpp b/AST/Stmt.cpp
index 8e1abda..28681c6 100644
--- a/AST/Stmt.cpp
+++ b/AST/Stmt.cpp
@@ -209,3 +209,11 @@
   return &SubStmts[0]+END_TRY; 
 }
 
+// ObjcAtThrowStmt
+Stmt::child_iterator ObjcAtThrowStmt::child_begin() {
+  return &Throw;
+}
+
+Stmt::child_iterator ObjcAtThrowStmt::child_end() {
+  return &Throw+1;
+}
diff --git a/AST/StmtPrinter.cpp b/AST/StmtPrinter.cpp
index d42a166..7fa553d 100644
--- a/AST/StmtPrinter.cpp
+++ b/AST/StmtPrinter.cpp
@@ -361,6 +361,15 @@
   Indent() << "@catch (...) { /* todo */ } \n";
 }
 
+void StmtPrinter::VisitObjcAtThrowStmt (ObjcAtThrowStmt *Node) {
+  Indent() << "@throw";
+  if (Node->getThrowExpr()) {
+    OS << " ";
+    PrintExpr(Node->getThrowExpr());
+  }
+  OS << ";\n";
+}
+
 //===----------------------------------------------------------------------===//
 //  Expr printing methods.
 //===----------------------------------------------------------------------===//
diff --git a/Parse/ParseObjc.cpp b/Parse/ParseObjc.cpp
index 4290fc5..a149b86 100644
--- a/Parse/ParseObjc.cpp
+++ b/Parse/ParseObjc.cpp
@@ -1052,16 +1052,18 @@
 ///  objc-throw-statement:
 ///    throw expression[opt];
 ///
-Parser::DeclTy *Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
+Parser::StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
+  ExprResult Res;
   ConsumeToken(); // consume throw
   if (Tok.isNot(tok::semi)) {
-    ExprResult Res = ParseExpression();
+    Res = ParseExpression();
     if (Res.isInvalid) {
       SkipUntil(tok::semi);
-      return 0;
+      return true;
     }
   }
-  return 0;
+  ConsumeToken(); // consume ';'
+  return Actions.ActOnObjcAtThrowStmt(atLoc, Res.Val);
 }
 
 ///  objc-try-catch-statement:
diff --git a/Sema/Sema.h b/Sema/Sema.h
index 01ac1e4..2781b16 100644
--- a/Sema/Sema.h
+++ b/Sema/Sema.h
@@ -350,6 +350,9 @@
                                         StmtTy *Try, 
                                         StmtTy *Catch, StmtTy *Finally);
   
+  virtual StmtResult ActOnObjcAtThrowStmt(SourceLocation AtLoc, 
+                                          StmtTy *Throw);
+  
   //===--------------------------------------------------------------------===//
   // Expression Parsing Callbacks: SemaExpr.cpp.
 
diff --git a/Sema/SemaStmt.cpp b/Sema/SemaStmt.cpp
index b495bb8..65acf0b 100644
--- a/Sema/SemaStmt.cpp
+++ b/Sema/SemaStmt.cpp
@@ -675,6 +675,11 @@
   return TS;
 }
 
+Action::StmtResult
+Sema::ActOnObjcAtThrowStmt(SourceLocation AtLoc, StmtTy *Throw) {
+  ObjcAtThrowStmt *TS = new ObjcAtThrowStmt(AtLoc, static_cast<Stmt*>(Throw));
+  return TS;
+}
 
 
 
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 67cf0c0..d1a7415 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -800,6 +800,33 @@
     
 };
 
+/// ObjcAtThrowStmt - This represents objective-c's @throw statement.
+class ObjcAtThrowStmt : public Stmt {
+private:
+  Stmt *Throw;
+  SourceLocation AtThrowLoc;
+
+public:
+  ObjcAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
+  : Stmt(ObjcAtThrowStmtClass), Throw(throwExpr) {
+    AtThrowLoc = atThrowLoc;
+  }
+  
+  Expr *const getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
+  
+  virtual SourceRange getSourceRange() const { 
+    return SourceRange(AtThrowLoc, Throw->getLocEnd()); 
+  }
+  
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjcAtThrowStmtClass;
+  }
+  static bool classof(const ObjcAtThrowStmt *) { return true; }
+  
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+};
+
 }  // end namespace clang
 
 #endif
diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def
index b94e6c3..db87975 100644
--- a/include/clang/AST/StmtNodes.def
+++ b/include/clang/AST/StmtNodes.def
@@ -48,8 +48,9 @@
 STMT(19, ObjcAtTryStmt        , Stmt)
 STMT(20, ObjcAtCatchStmt      , Stmt)
 STMT(21, ObjcAtFinallyStmt    , Stmt)
+STMT(22, ObjcAtThrowStmt      , Stmt)
 
-LAST_STMT(21)
+LAST_STMT(22)
 
 FIRST_EXPR(31)
 // Expressions.
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index 41c60f4..acdd27e 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -305,6 +305,12 @@
                                         StmtTy *Catch, StmtTy *Finally) {
     return 0;
   }
+  
+  virtual StmtResult ActOnObjcAtThrowStmt(SourceLocation AtLoc, 
+                                          StmtTy *Throw) {
+    return 0;
+  }
+  
   //===--------------------------------------------------------------------===//
   // Expression Parsing Callbacks.
   //===--------------------------------------------------------------------===//
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 1bdf2e7..b7476a7 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -275,7 +275,6 @@
   DeclTy *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
   DeclTy *ParseObjCPropertySynthesize(SourceLocation atLoc);
   DeclTy *ParseObjCPropertyDynamic(SourceLocation atLoc);
-  DeclTy *ParseObjCThrowStmt(SourceLocation atLoc);
   
   IdentifierInfo *ParseObjCSelector(SourceLocation &MethodLocation);
   // Definitions for Objective-c context sensitive keywords recognition.
@@ -389,6 +388,7 @@
   StmtResult ParseReturnStatement();
   StmtResult ParseAsmStatement();
   StmtResult ParseObjCTryStmt(SourceLocation atLoc);
+  StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
   void ParseAsmOperandsOpt();
 
   //===--------------------------------------------------------------------===//