]> granicus.if.org Git - clang/commitdiff
add parsing, ast building and pretty printing support for C++ throw expressions.
authorChris Lattner <sabre@nondot.org>
Tue, 26 Feb 2008 00:51:44 +0000 (00:51 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 26 Feb 2008 00:51:44 +0000 (00:51 +0000)
Patch by Mike Stump!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47582 91177308-0d34-0410-b5e6-96231b3b80d8

AST/ExprCXX.cpp
AST/StmtPrinter.cpp
Parse/ParseExpr.cpp
Parse/ParseExprCXX.cpp
Sema/Sema.h
Sema/SemaExprCXX.cpp
include/clang/AST/ExprCXX.h
include/clang/AST/StmtNodes.def
include/clang/Parse/Action.h
include/clang/Parse/Parser.h

index 0646823af9ce7a1617398c127ab5ef632388ee46..3bc32e75d87e3cb9c86952850b68bed69c112a50 100644 (file)
@@ -23,7 +23,6 @@ using namespace clang;
 Stmt::child_iterator CXXCastExpr::child_begin() {
   return reinterpret_cast<Stmt**>(&Op);
 }
-
 Stmt::child_iterator CXXCastExpr::child_end() {
   return reinterpret_cast<Stmt**>(&Op)+1;
 }
@@ -35,3 +34,14 @@ Stmt::child_iterator CXXBoolLiteralExpr::child_begin() {
 Stmt::child_iterator CXXBoolLiteralExpr::child_end() {
   return child_iterator();
 }
+
+// CXXThrowExpr
+Stmt::child_iterator CXXThrowExpr::child_begin() {
+  return reinterpret_cast<Stmt**>(&Op);
+}
+Stmt::child_iterator CXXThrowExpr::child_end() {
+  // If Op is 0, we are processing throw; which has no children.
+  if (Op == 0)
+    return reinterpret_cast<Stmt**>(&Op)+0;
+  return reinterpret_cast<Stmt**>(&Op)+1;
+}
index 74d94eacf62640784936141889229ebe3ce3e8de..ba82b7fcff760a0d4cab8bdcd85d562429181ff7 100644 (file)
@@ -780,6 +780,15 @@ void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
   OS << (Node->getValue() ? "true" : "false");
 }
 
+void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
+  if (Node->getSubExpr() == 0)
+    OS << "throw";
+  else {
+    OS << "throw ";
+    PrintExpr(Node->getSubExpr());
+  }
+}
+
 // Obj-C 
 
 void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
index 67ce5f1a545bdec9fc416772137ae29870bf5678..46714b73ea7e3e811876c134eb7514f8d7bb1d22 100644 (file)
@@ -157,6 +157,7 @@ static prec::Level getBinOpPrecedence(tok::TokenKind Kind) {
 ///       assignment-expression: [C99 6.5.16]
 ///         conditional-expression
 ///         unary-expression assignment-operator assignment-expression
+/// [C++]   throw-expression [C++ 15]
 ///
 ///       assignment-operator: one of
 ///         = *= /= %= += -= <<= >>= &= ^= |=
@@ -166,6 +167,9 @@ static prec::Level getBinOpPrecedence(tok::TokenKind Kind) {
 ///         expression ',' assignment-expression
 ///
 Parser::ExprResult Parser::ParseExpression() {
+  if (Tok.is(tok::kw_throw))
+    return ParseThrowExpression();
+
   ExprResult LHS = ParseCastExpression(false);
   if (LHS.isInvalid) return LHS;
   
@@ -187,6 +191,9 @@ Parser::ExprResult Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
 /// ParseAssignmentExpression - Parse an expr that doesn't include commas.
 ///
 Parser::ExprResult Parser::ParseAssignmentExpression() {
+  if (Tok.is(tok::kw_throw))
+    return ParseThrowExpression();
+
   ExprResult LHS = ParseCastExpression(false);
   if (LHS.isInvalid) return LHS;
   
index adf4f8d353425ca486cc0bb6dbc80303dcf2f3dc..6b42fb5b0892ca65e504810588b9b12ad3f9abf7 100644 (file)
@@ -76,3 +76,24 @@ Parser::ExprResult Parser::ParseCXXBoolLiteral() {
   tok::TokenKind Kind = Tok.getKind();
   return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
 }
+
+/// ParseThrowExpression - This handles the C++ throw expression.
+///
+///       throw-expression: [C++ 15]
+///         'throw' assignment-expression[opt]
+Parser::ExprResult Parser::ParseThrowExpression() {
+  assert(Tok.is(tok::kw_throw) && "Not throw!");
+
+  ExprResult Expr;
+
+  SourceLocation ThrowLoc = ConsumeToken();           // Eat the throw token.
+  // FIXME: Anything that isn't an assignment-expression should bail out now.
+  if (Tok.is(tok::semi) || Tok.is(tok::r_paren) || Tok.is(tok::colon) ||
+      Tok.is(tok::comma))
+    return Actions.ActOnCXXThrow(ThrowLoc);
+
+  Expr = ParseAssignmentExpression();
+  if (!Expr.isInvalid)
+    Expr = Actions.ActOnCXXThrow(ThrowLoc, Expr.Val);
+  return Expr;
+}
index 95bc3b7fccd9ef91cc25610120a8a3cf59f46ccf..c2d249a9c6d3390402ece046bafe990a3891460f 100644 (file)
@@ -510,6 +510,10 @@ public:
   virtual ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc,
                                          tok::TokenKind Kind);
   
+  //// ActOnCXXThrow -  Parse throw expressions.
+  virtual ExprResult ActOnCXXThrow(SourceLocation OpLoc,
+                                   ExprTy *expr);
+
   // ParseObjCStringLiteral - Parse Objective-C string literals.
   virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, 
                                             ExprTy **Strings,
index 516e50756e303f09beaab0dc1f1159ef9df4c72a..e49a43c4728cc6cfcd97026a01eca21d11677eed 100644 (file)
@@ -43,3 +43,9 @@ Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
          "Unknown C++ Boolean value!");
   return new CXXBoolLiteralExpr(Kind == tok::kw_true, Context.BoolTy, OpLoc);
 }
+
+/// ActOnCXXThrow - Parse throw expressions.
+Action::ExprResult
+Sema::ActOnCXXThrow(SourceLocation OpLoc, ExprTy *E) {
+  return new CXXThrowExpr((Expr*)E, Context.VoidTy, OpLoc);
+}
index 0fa38374c058c760cd26a7394a8ca838920bc417..357fb9538f2cc128b0cbdcd240b0538bebec189e 100644 (file)
@@ -95,6 +95,38 @@ namespace clang {
     virtual child_iterator child_end();
   };
 
+  ///  CXXThrowExpr - [C++ 15] C++ Throw Expression.  This handles
+  ///  'throw' and 'throw' assignment-expression.  When
+  ///  assignment-expression isn't present, Op will be null.
+  ///
+  class CXXThrowExpr : public Expr {
+    Expr *Op;
+    SourceLocation ThrowLoc;
+  public:
+    // Ty is the void type which is used as the result type of the
+    // exepression.  The l is the location of the throw keyword.  expr
+    // can by null, if the optional expression to throw isn't present.
+    CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l) :
+      Expr(CXXThrowExprClass, Ty), Op(expr), ThrowLoc(l) {}
+    const Expr *getSubExpr() const { return Op; }
+    Expr *getSubExpr() { return Op; }
+
+    virtual SourceRange getSourceRange() const {
+      if (getSubExpr() == 0)
+        return SourceRange(ThrowLoc, ThrowLoc);
+      return SourceRange(ThrowLoc, getSubExpr()->getSourceRange().getEnd());
+    }
+
+    static bool classof(const Stmt *T) {
+      return T->getStmtClass() == CXXThrowExprClass;
+    }
+    static bool classof(const CXXThrowExpr *) { return true; }
+
+    // Iterators
+    virtual child_iterator child_begin();
+    virtual child_iterator child_end();
+  };
+
 }  // end namespace clang
 
 #endif
index a8083e6adbe3b11f74d95679b58a53f1bb9c5341..4c0fd7a242d23e72ca5a0b8415f706b0e9c97b13 100644 (file)
@@ -90,6 +90,7 @@ STMT(58, ChooseExpr           , Expr)
 // C++ Expressions.
 STMT(60, CXXCastExpr          , Expr)
 STMT(61, CXXBoolLiteralExpr   , Expr)
+STMT(62, CXXThrowExpr         , Expr)
 
 // Obj-C Expressions.
 STMT(70, ObjCStringLiteral    , Expr)
index 281b9b7be8e5e404d9da455fad1319eb23a73183..63d9a72c909626f9690c0f816984e82020f95fef 100644 (file)
@@ -519,6 +519,12 @@ public:
                                          tok::TokenKind Kind) {
     return 0;
   }
+
+  /// ActOnCXXThrow - Parse throw expressions.
+  virtual ExprResult ActOnCXXThrow(SourceLocation OpLoc,
+                                   ExprTy *Op = 0) {
+    return 0;
+  }
   //===----------------------- Obj-C Declarations -------------------------===//
   
   // ActOnStartClassInterface - this action is called immdiately after parsing
index 68c7457a51a85ca2c5bfd0491b3b1b1cf4fb2605..860e5d700fb62d15ce9ba53db4fd47b61afb0c77 100644 (file)
@@ -353,6 +353,10 @@ private:
   // C++ 5.2p1: C++ Casts
   ExprResult ParseCXXCasts();
 
+  //===--------------------------------------------------------------------===//
+  // C++ 15: C++ Throw Expression
+  ExprResult ParseThrowExpression();
+
   //===--------------------------------------------------------------------===//
   // C++ 2.13.5: C++ Boolean Literals
   ExprResult ParseCXXBoolLiteral();