AST build for @catch clause (this is work in progress).

llvm-svn: 43628
This commit is contained in:
Fariborz Jahanian 2007-11-01 23:59:59 +00:00
parent ae077d232c
commit 9e63b98de7
6 changed files with 68 additions and 19 deletions

View File

@ -194,8 +194,10 @@ Stmt::child_iterator AsmStmt::child_begin() { return child_iterator(); }
Stmt::child_iterator AsmStmt::child_end() { return child_iterator(); }
// ObjcAtCatchStmt
Stmt::child_iterator ObjcAtCatchStmt::child_begin() { return &AtCatchStmt; }
Stmt::child_iterator ObjcAtCatchStmt::child_end() { return &AtCatchStmt+1; }
Stmt::child_iterator ObjcAtCatchStmt::child_begin() { return &SubExprs[0]; }
Stmt::child_iterator ObjcAtCatchStmt::child_end() {
return &SubExprs[0]+END_EXPR;
}
// ObjcAtFinallyStmt
Stmt::child_iterator ObjcAtFinallyStmt::child_begin() { return &AtFinallyStmt; }
@ -203,5 +205,7 @@ Stmt::child_iterator ObjcAtFinallyStmt::child_end() { return &AtFinallyStmt+1; }
// ObjcAtTryStmt
Stmt::child_iterator ObjcAtTryStmt::child_begin() { return &SubStmts[0]; }
Stmt::child_iterator ObjcAtTryStmt::child_end() { return &SubStmts[0]+1; }
Stmt::child_iterator ObjcAtTryStmt::child_end() {
return &SubStmts[0]+END_TRY;
}

View File

@ -13,6 +13,7 @@
#include "clang/Parse/Parser.h"
#include "clang/Parse/DeclSpec.h"
#include "clang/Parse/Scope.h"
#include "clang/Basic/Diagnostic.h"
#include "llvm/ADT/SmallVector.h"
using namespace clang;
@ -1053,28 +1054,38 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
Diag (Tok, diag::err_expected_lbrace);
return true;
}
StmtResult CatchStmts;
StmtResult TryBody = ParseCompoundStatementBody();
while (Tok.is(tok::at)) {
ConsumeToken();
SourceLocation AtCatchLoc = ConsumeToken();
if (Tok.getIdentifierInfo()->getObjCKeywordID() == tok::objc_catch) {
SourceLocation catchLoc = ConsumeToken(); // consume catch
StmtTy *FirstPart = 0;
ConsumeToken(); // consume catch
if (Tok.is(tok::l_paren)) {
ConsumeParen();
EnterScope(Scope::DeclScope);
if (Tok.isNot(tok::ellipsis)) {
DeclSpec DS;
ParseDeclarationSpecifiers(DS);
// Parse the parameter-declaration.
// FIXME: BlockContext may not be the right context!
Declarator ParmDecl(DS, Declarator::BlockContext);
ParseDeclarator(ParmDecl);
// FIXME: Is BlockContext right?
Declarator DeclaratorInfo(DS, Declarator::BlockContext);
ParseDeclarator(DeclaratorInfo);
StmtResult stmtResult = Actions.ActOnDeclarator(CurScope,
DeclaratorInfo, 0);
FirstPart = stmtResult.isInvalid ? 0 : stmtResult.Val;
}
else
ConsumeToken(); // consume '...'
ConsumeParen();
SourceLocation RParenLoc = ConsumeParen();
StmtResult CatchBody = ParseCompoundStatementBody();
if (CatchBody.isInvalid)
CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
CatchStmts = Actions.ActOnObjcAtCatchStmt(AtCatchLoc, RParenLoc,
FirstPart, CatchBody.Val, CatchStmts.Val);
ExitScope();
}
else {
Diag(catchLoc, diag::err_expected_lparen_after, "@catch clause");
Diag(AtCatchLoc, diag::err_expected_lparen_after, "@catch clause");
return true;
}
catch_or_finally_seen = true;

View File

@ -339,6 +339,10 @@ public:
virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc,
SourceLocation RParenLoc);
virtual StmtResult ActOnObjcAtCatchStmt(SourceLocation AtLoc,
SourceLocation RParen, StmtTy *Parm,
StmtTy *Body, StmtTy *CatchList);
//===--------------------------------------------------------------------===//
// Expression Parsing Callbacks: SemaExpr.cpp.

View File

@ -648,3 +648,14 @@ Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
SourceLocation RParenLoc) {
return new AsmStmt(AsmLoc, RParenLoc);
}
Action::StmtResult
Sema::ActOnObjcAtCatchStmt(SourceLocation AtLoc,
SourceLocation RParen, StmtTy *Parm,
StmtTy *Body, StmtTy *CatchList) {
ObjcAtCatchStmt *CS = new ObjcAtCatchStmt(AtLoc, RParen,
static_cast<Stmt*>(Parm), static_cast<Stmt*>(Body),
static_cast<Stmt*>(CatchList));
return CatchList ? CatchList : CS;
}

View File

@ -663,19 +663,31 @@ class ObjcAtCatchStmt : public Stmt {
private:
// Points to next @catch statement, or null
ObjcAtCatchStmt *NextAtCatchStmt;
ScopedDecl *AtCatchDeclarator;
Stmt *AtCatchStmt;
enum { SELECTOR, BODY, END_EXPR };
Stmt *SubExprs[END_EXPR];
SourceLocation AtCatchLoc, RParenLoc;
public:
ObjcAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
ScopedDecl *atCatchDeclarator, Stmt *atCatchStmt)
: Stmt(ObjcAtCatchStmtClass), NextAtCatchStmt(0),
AtCatchDeclarator(atCatchDeclarator), AtCatchStmt(atCatchStmt),
AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {}
Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList)
: Stmt(ObjcAtCatchStmtClass),
AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {
SubExprs[SELECTOR] = catchVarStmtDecl;
SubExprs[BODY] = atCatchStmt;
SubExprs[END_EXPR] = NULL;
if (!atCatchList)
NextAtCatchStmt = NULL;
else {
ObjcAtCatchStmt *AtCatchList =
static_cast<ObjcAtCatchStmt*>(atCatchList);
while (AtCatchList->NextAtCatchStmt)
AtCatchList = AtCatchList->NextAtCatchStmt;
AtCatchList->NextAtCatchStmt = this;
}
}
virtual SourceRange getSourceRange() const {
return SourceRange(AtCatchLoc, AtCatchStmt->getLocEnd());
return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd());
}
static bool classof(const Stmt *T) {

View File

@ -288,6 +288,13 @@ public:
return 0;
}
// Objective-c statements
virtual StmtResult ActOnObjcAtCatchStmt(SourceLocation AtLoc,
SourceLocation RParen, StmtTy *Parm,
StmtTy *Body, StmtTy *CatchList) {
return 0;
}
//===--------------------------------------------------------------------===//
// Expression Parsing Callbacks.
//===--------------------------------------------------------------------===//