Stmt::child_iterator CXXCastExpr::child_begin() {
return reinterpret_cast<Stmt**>(&Op);
}
-
Stmt::child_iterator CXXCastExpr::child_end() {
return reinterpret_cast<Stmt**>(&Op)+1;
}
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;
+}
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) {
/// assignment-expression: [C99 6.5.16]
/// conditional-expression
/// unary-expression assignment-operator assignment-expression
+/// [C++] throw-expression [C++ 15]
///
/// assignment-operator: one of
/// = *= /= %= += -= <<= >>= &= ^= |=
/// expression ',' assignment-expression
///
Parser::ExprResult Parser::ParseExpression() {
+ if (Tok.is(tok::kw_throw))
+ return ParseThrowExpression();
+
ExprResult LHS = ParseCastExpression(false);
if (LHS.isInvalid) return LHS;
/// 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;
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;
+}
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,
"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);
+}
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
// C++ Expressions.
STMT(60, CXXCastExpr , Expr)
STMT(61, CXXBoolLiteralExpr , Expr)
+STMT(62, CXXThrowExpr , Expr)
// Obj-C Expressions.
STMT(70, ObjCStringLiteral , Expr)
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
// C++ 5.2p1: C++ Casts
ExprResult ParseCXXCasts();
+ //===--------------------------------------------------------------------===//
+ // C++ 15: C++ Throw Expression
+ ExprResult ParseThrowExpression();
+
//===--------------------------------------------------------------------===//
// C++ 2.13.5: C++ Boolean Literals
ExprResult ParseCXXBoolLiteral();