зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
a73349d332
Коммит
50dd289f45
|
@ -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();
|
||||
|
|
Загрузка…
Ссылка в новой задаче