From 50dd289f45738ed22b7583d52ed2525b927042ff Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 26 Feb 2008 00:51:44 +0000 Subject: [PATCH] add parsing, ast building and pretty printing support for C++ throw expressions. Patch by Mike Stump! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47582 91177308-0d34-0410-b5e6-96231b3b80d8 --- AST/ExprCXX.cpp | 12 +++++++++++- AST/StmtPrinter.cpp | 9 +++++++++ Parse/ParseExpr.cpp | 7 +++++++ Parse/ParseExprCXX.cpp | 21 +++++++++++++++++++++ Sema/Sema.h | 4 ++++ Sema/SemaExprCXX.cpp | 6 ++++++ include/clang/AST/ExprCXX.h | 32 ++++++++++++++++++++++++++++++++ include/clang/AST/StmtNodes.def | 1 + include/clang/Parse/Action.h | 6 ++++++ include/clang/Parse/Parser.h | 4 ++++ 10 files changed, 101 insertions(+), 1 deletion(-) diff --git a/AST/ExprCXX.cpp b/AST/ExprCXX.cpp index 0646823af9..3bc32e75d8 100644 --- a/AST/ExprCXX.cpp +++ b/AST/ExprCXX.cpp @@ -23,7 +23,6 @@ using namespace clang; Stmt::child_iterator CXXCastExpr::child_begin() { return reinterpret_cast(&Op); } - Stmt::child_iterator CXXCastExpr::child_end() { return reinterpret_cast(&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(&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(&Op)+0; + return reinterpret_cast(&Op)+1; +} diff --git a/AST/StmtPrinter.cpp b/AST/StmtPrinter.cpp index 74d94eacf6..ba82b7fcff 100644 --- a/AST/StmtPrinter.cpp +++ b/AST/StmtPrinter.cpp @@ -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) { diff --git a/Parse/ParseExpr.cpp b/Parse/ParseExpr.cpp index 67ce5f1a54..46714b73ea 100644 --- a/Parse/ParseExpr.cpp +++ b/Parse/ParseExpr.cpp @@ -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; diff --git a/Parse/ParseExprCXX.cpp b/Parse/ParseExprCXX.cpp index adf4f8d353..6b42fb5b08 100644 --- a/Parse/ParseExprCXX.cpp +++ b/Parse/ParseExprCXX.cpp @@ -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; +} diff --git a/Sema/Sema.h b/Sema/Sema.h index 95bc3b7fcc..c2d249a9c6 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -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, diff --git a/Sema/SemaExprCXX.cpp b/Sema/SemaExprCXX.cpp index 516e50756e..e49a43c472 100644 --- a/Sema/SemaExprCXX.cpp +++ b/Sema/SemaExprCXX.cpp @@ -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); +} diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 0fa38374c0..357fb9538f 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -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 diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def index a8083e6adb..4c0fd7a242 100644 --- a/include/clang/AST/StmtNodes.def +++ b/include/clang/AST/StmtNodes.def @@ -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) diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 281b9b7be8..63d9a72c90 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -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 diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 68c7457a51..860e5d700f 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -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(); -- 2.40.0