forked from OSchip/llvm-project
add parsing, ast building and pretty printing support for C++ throw expressions.
Patch by Mike Stump! llvm-svn: 47582
This commit is contained in:
parent
7768313c13
commit
b7e656b177
|
@ -23,7 +23,6 @@ using namespace clang;
|
||||||
Stmt::child_iterator CXXCastExpr::child_begin() {
|
Stmt::child_iterator CXXCastExpr::child_begin() {
|
||||||
return reinterpret_cast<Stmt**>(&Op);
|
return reinterpret_cast<Stmt**>(&Op);
|
||||||
}
|
}
|
||||||
|
|
||||||
Stmt::child_iterator CXXCastExpr::child_end() {
|
Stmt::child_iterator CXXCastExpr::child_end() {
|
||||||
return reinterpret_cast<Stmt**>(&Op)+1;
|
return reinterpret_cast<Stmt**>(&Op)+1;
|
||||||
}
|
}
|
||||||
|
@ -35,3 +34,14 @@ Stmt::child_iterator CXXBoolLiteralExpr::child_begin() {
|
||||||
Stmt::child_iterator CXXBoolLiteralExpr::child_end() {
|
Stmt::child_iterator CXXBoolLiteralExpr::child_end() {
|
||||||
return child_iterator();
|
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");
|
OS << (Node->getValue() ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
|
||||||
|
if (Node->getSubExpr() == 0)
|
||||||
|
OS << "throw";
|
||||||
|
else {
|
||||||
|
OS << "throw ";
|
||||||
|
PrintExpr(Node->getSubExpr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Obj-C
|
// Obj-C
|
||||||
|
|
||||||
void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
|
void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
|
||||||
|
|
|
@ -157,6 +157,7 @@ static prec::Level getBinOpPrecedence(tok::TokenKind Kind) {
|
||||||
/// assignment-expression: [C99 6.5.16]
|
/// assignment-expression: [C99 6.5.16]
|
||||||
/// conditional-expression
|
/// conditional-expression
|
||||||
/// unary-expression assignment-operator assignment-expression
|
/// unary-expression assignment-operator assignment-expression
|
||||||
|
/// [C++] throw-expression [C++ 15]
|
||||||
///
|
///
|
||||||
/// assignment-operator: one of
|
/// assignment-operator: one of
|
||||||
/// = *= /= %= += -= <<= >>= &= ^= |=
|
/// = *= /= %= += -= <<= >>= &= ^= |=
|
||||||
|
@ -166,6 +167,9 @@ static prec::Level getBinOpPrecedence(tok::TokenKind Kind) {
|
||||||
/// expression ',' assignment-expression
|
/// expression ',' assignment-expression
|
||||||
///
|
///
|
||||||
Parser::ExprResult Parser::ParseExpression() {
|
Parser::ExprResult Parser::ParseExpression() {
|
||||||
|
if (Tok.is(tok::kw_throw))
|
||||||
|
return ParseThrowExpression();
|
||||||
|
|
||||||
ExprResult LHS = ParseCastExpression(false);
|
ExprResult LHS = ParseCastExpression(false);
|
||||||
if (LHS.isInvalid) return LHS;
|
if (LHS.isInvalid) return LHS;
|
||||||
|
|
||||||
|
@ -187,6 +191,9 @@ Parser::ExprResult Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
|
||||||
/// ParseAssignmentExpression - Parse an expr that doesn't include commas.
|
/// ParseAssignmentExpression - Parse an expr that doesn't include commas.
|
||||||
///
|
///
|
||||||
Parser::ExprResult Parser::ParseAssignmentExpression() {
|
Parser::ExprResult Parser::ParseAssignmentExpression() {
|
||||||
|
if (Tok.is(tok::kw_throw))
|
||||||
|
return ParseThrowExpression();
|
||||||
|
|
||||||
ExprResult LHS = ParseCastExpression(false);
|
ExprResult LHS = ParseCastExpression(false);
|
||||||
if (LHS.isInvalid) return LHS;
|
if (LHS.isInvalid) return LHS;
|
||||||
|
|
||||||
|
|
|
@ -76,3 +76,24 @@ Parser::ExprResult Parser::ParseCXXBoolLiteral() {
|
||||||
tok::TokenKind Kind = Tok.getKind();
|
tok::TokenKind Kind = Tok.getKind();
|
||||||
return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
|
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,
|
virtual ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc,
|
||||||
tok::TokenKind Kind);
|
tok::TokenKind Kind);
|
||||||
|
|
||||||
|
//// ActOnCXXThrow - Parse throw expressions.
|
||||||
|
virtual ExprResult ActOnCXXThrow(SourceLocation OpLoc,
|
||||||
|
ExprTy *expr);
|
||||||
|
|
||||||
// ParseObjCStringLiteral - Parse Objective-C string literals.
|
// ParseObjCStringLiteral - Parse Objective-C string literals.
|
||||||
virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
|
virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
|
||||||
ExprTy **Strings,
|
ExprTy **Strings,
|
||||||
|
|
|
@ -43,3 +43,9 @@ Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
|
||||||
"Unknown C++ Boolean value!");
|
"Unknown C++ Boolean value!");
|
||||||
return new CXXBoolLiteralExpr(Kind == tok::kw_true, Context.BoolTy, OpLoc);
|
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();
|
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
|
} // end namespace clang
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -90,6 +90,7 @@ STMT(58, ChooseExpr , Expr)
|
||||||
// C++ Expressions.
|
// C++ Expressions.
|
||||||
STMT(60, CXXCastExpr , Expr)
|
STMT(60, CXXCastExpr , Expr)
|
||||||
STMT(61, CXXBoolLiteralExpr , Expr)
|
STMT(61, CXXBoolLiteralExpr , Expr)
|
||||||
|
STMT(62, CXXThrowExpr , Expr)
|
||||||
|
|
||||||
// Obj-C Expressions.
|
// Obj-C Expressions.
|
||||||
STMT(70, ObjCStringLiteral , Expr)
|
STMT(70, ObjCStringLiteral , Expr)
|
||||||
|
|
|
@ -519,6 +519,12 @@ public:
|
||||||
tok::TokenKind Kind) {
|
tok::TokenKind Kind) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ActOnCXXThrow - Parse throw expressions.
|
||||||
|
virtual ExprResult ActOnCXXThrow(SourceLocation OpLoc,
|
||||||
|
ExprTy *Op = 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
//===----------------------- Obj-C Declarations -------------------------===//
|
//===----------------------- Obj-C Declarations -------------------------===//
|
||||||
|
|
||||||
// ActOnStartClassInterface - this action is called immdiately after parsing
|
// ActOnStartClassInterface - this action is called immdiately after parsing
|
||||||
|
|
|
@ -353,6 +353,10 @@ private:
|
||||||
// C++ 5.2p1: C++ Casts
|
// C++ 5.2p1: C++ Casts
|
||||||
ExprResult ParseCXXCasts();
|
ExprResult ParseCXXCasts();
|
||||||
|
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
// C++ 15: C++ Throw Expression
|
||||||
|
ExprResult ParseThrowExpression();
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// C++ 2.13.5: C++ Boolean Literals
|
// C++ 2.13.5: C++ Boolean Literals
|
||||||
ExprResult ParseCXXBoolLiteral();
|
ExprResult ParseCXXBoolLiteral();
|
||||||
|
|
Loading…
Reference in New Issue