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
This commit is contained in:
Chris Lattner 2008-02-26 00:51:44 +00:00
Родитель a73349d332
Коммит 50dd289f45
10 изменённых файлов: 101 добавлений и 1 удалений

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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,

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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)

Просмотреть файл

@ -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

Просмотреть файл

@ -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();