diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2007-10-04 20:19:06 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2007-10-04 20:19:06 +0000 |
commit | b384d329e0b727d4f2effa28fbb9aba2ac420e7b (patch) | |
tree | b3c02972d19576e3d75e35ae073fdbd794712b41 | |
parent | 5951965a39c01764e4777e16b7089874512ebc5a (diff) |
this patch accomodates clattner's comments on expression processing in @try-statement.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42611 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | Parse/ParseExpr.cpp | 2 | ||||
-rw-r--r-- | Parse/ParseObjc.cpp | 14 | ||||
-rw-r--r-- | Parse/ParseStmt.cpp | 27 | ||||
-rw-r--r-- | Sema/SemaDecl.cpp | 33 | ||||
-rw-r--r-- | include/clang/Parse/Parser.h | 8 | ||||
-rw-r--r-- | test/Parser/encode.m | 8 | ||||
-rw-r--r-- | test/Parser/objc-try-catch-1.m | 4 |
7 files changed, 58 insertions, 38 deletions
diff --git a/Parse/ParseExpr.cpp b/Parse/ParseExpr.cpp index 4608898d99..1b261aae26 100644 --- a/Parse/ParseExpr.cpp +++ b/Parse/ParseExpr.cpp @@ -177,7 +177,7 @@ Parser::ExprResult Parser::ParseExpression() { /// routine is necessary to disambiguate @try-statement from, /// for example, @encode-expression. /// -Parser::ExprResult Parser::ParseExpressionWithLeadingAt(SourceLocation &AtLoc) { +Parser::ExprResult Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) { ExprResult LHS = ParseObjCExpression(AtLoc); if (LHS.isInvalid) return LHS; diff --git a/Parse/ParseObjc.cpp b/Parse/ParseObjc.cpp index c55768704d..dff6e0c9e6 100644 --- a/Parse/ParseObjc.cpp +++ b/Parse/ParseObjc.cpp @@ -1067,10 +1067,10 @@ Parser::DeclTy *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { /// objc-throw-statement: /// throw expression[opt]; /// -Parser::DeclTy *Parser::ParseObjCThrowStmt(SourceLocation &atLoc) { +Parser::DeclTy *Parser::ParseObjCThrowStmt(SourceLocation atLoc) { ConsumeToken(); // consume throw if (Tok.getKind() != tok::semi) { - ExprResult Res = ParseAssignmentExpression(); + ExprResult Res = ParseExpression(); if (Res.isInvalid) { SkipUntil(tok::semi); return 0; @@ -1090,7 +1090,7 @@ Parser::DeclTy *Parser::ParseObjCThrowStmt(SourceLocation &atLoc) { /// parameter-declaration /// '...' [OBJC2] /// -Parser::DeclTy *Parser::ParseObjCTryStmt(SourceLocation &atLoc) { +Parser::DeclTy *Parser::ParseObjCTryStmt(SourceLocation atLoc) { bool catch_or_finally_seen = false; ConsumeToken(); // consume try if (Tok.getKind() != tok::l_brace) { @@ -1172,21 +1172,21 @@ void Parser::ParseObjCClassMethodDefinition() { StmtResult FnBody = ParseCompoundStatementBody(); } -Parser::ExprResult Parser::ParseObjCExpression(SourceLocation &AtLoc) { +Parser::ExprResult Parser::ParseObjCExpression(SourceLocation AtLoc) { switch (Tok.getKind()) { case tok::string_literal: // primary-expression: string-literal case tok::wide_string_literal: - return ParseObjCStringLiteral(); + return ParsePostfixExpressionSuffix(ParseObjCStringLiteral()); default: break; } switch (Tok.getIdentifierInfo()->getObjCKeywordID()) { case tok::objc_encode: - return ParseObjCEncodeExpression(); + return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression()); case tok::objc_protocol: - return ParseObjCProtocolExpression(); + return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression()); default: Diag(AtLoc, diag::err_unexpected_at); SkipUntil(tok::semi); diff --git a/Parse/ParseStmt.cpp b/Parse/ParseStmt.cpp index d37973b013..7dc6a62e84 100644 --- a/Parse/ParseStmt.cpp +++ b/Parse/ParseStmt.cpp @@ -34,8 +34,8 @@ using namespace clang; /// selection-statement /// iteration-statement /// jump-statement -/// [OBC] objc-throw-statement [TODO] -/// [OBC] objc-try-catch-statement [TODO] +/// [OBC] objc-throw-statement +/// [OBC] objc-try-catch-statement /// [OBC] objc-synchronized-statement [TODO] /// [GNU] asm-statement /// [OMP] openmp-construct [TODO] @@ -64,9 +64,9 @@ using namespace clang; /// 'return' expression[opt] ';' /// [GNU] 'goto' '*' expression ';' /// -/// [OBC] objc-throw-statement: [TODO] -/// [OBC] '@' 'throw' expression ';' [TODO] -/// [OBC] '@' 'throw' ';' [TODO] +/// [OBC] objc-throw-statement: +/// [OBC] '@' 'throw' expression ';' +/// [OBC] '@' 'throw' ';' /// Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) { const char *SemiError = 0; @@ -91,19 +91,28 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) { return ParseObjCTryStmt(AtLoc); else if (Tok.getIdentifierInfo()->getObjCKeywordID() == tok::objc_throw) return ParseObjCThrowStmt(AtLoc); + ExprResult Res = ParseExpressionWithLeadingAt(AtLoc); + if (Res.isInvalid) { + // If the expression is invalid, skip ahead to the next semicolon. Not + // doing this opens us up to the possibility of infinite loops if + // ParseExpression does not consume any tokens. + SkipUntil(tok::semi); + return true; + } + // Otherwise, eat the semicolon. + ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); + return Actions.ActOnExprStmt(Res.Val); } - // Fall thru. default: - if (Kind != tok::at && !OnlyStatement && isDeclarationSpecifier()) { + if (!OnlyStatement && isDeclarationSpecifier()) { return Actions.ActOnDeclStmt(ParseDeclaration(Declarator::BlockContext)); } else if (Tok.getKind() == tok::r_brace) { Diag(Tok, diag::err_expected_statement); return true; } else { // expression[opt] ';' - ExprResult Res = (Kind == tok::at) ? ParseExpressionWithLeadingAt(AtLoc) - : ParseExpression(); + ExprResult Res = ParseExpression(); if (Res.isInvalid) { // If the expression is invalid, skip ahead to the next semicolon. Not // doing this opens us up to the possibility of infinite loops if diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 2c7554b778..25dd0c9820 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -1729,27 +1729,28 @@ void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *ClassDecl, if (IDecl) ImplMethodsVsClassMethods(ImplClass, IDecl); } - else if (isa<ObjcCategoryImplDecl>(static_cast<Decl *>(ClassDecl))) { - ObjcCategoryImplDecl* CatImplClass = cast<ObjcCategoryImplDecl>( + else { + ObjcCategoryImplDecl* CatImplClass = dyn_cast<ObjcCategoryImplDecl>( static_cast<Decl*>(ClassDecl)); - CatImplClass->ObjcAddCatImplMethods(&insMethods[0], insMethods.size(), - &clsMethods[0], clsMethods.size()); - ObjcInterfaceDecl* IDecl = CatImplClass->getClassInterface(); - // Find category interface decl and then check that all methods declared - // in this interface is implemented in the category @implementation. - if (IDecl) { - for (ObjcCategoryDecl *Categories = IDecl->getListCategories(); - Categories; Categories = Categories->getNextClassCategory()) { - if (Categories->getCatName() == CatImplClass->getObjcCatName()) { - ImplCategoryMethodsVsIntfMethods(CatImplClass, Categories); - break; + if (CatImplClass) { + CatImplClass->ObjcAddCatImplMethods(&insMethods[0], insMethods.size(), + &clsMethods[0], clsMethods.size()); + ObjcInterfaceDecl* IDecl = CatImplClass->getClassInterface(); + // Find category interface decl and then check that all methods declared + // in this interface is implemented in the category @implementation. + if (IDecl) { + for (ObjcCategoryDecl *Categories = IDecl->getListCategories(); + Categories; Categories = Categories->getNextClassCategory()) { + if (Categories->getCatName() == CatImplClass->getObjcCatName()) { + ImplCategoryMethodsVsIntfMethods(CatImplClass, Categories); + break; + } } } } + else + assert(0 && "Sema::ActOnAddMethodsToObjcDecl(): Unknown DeclTy"); } - else - assert(0 && "Sema::ActOnAddMethodsToObjcDecl(): Unknown DeclTy"); - return; } Sema::DeclTy *Sema::ActOnMethodDeclaration(SourceLocation MethodLoc, diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index db83443442..ce98d9d7e5 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -272,8 +272,8 @@ private: DeclTy *ParseObjCAtAliasDeclaration(SourceLocation atLoc); DeclTy *ParseObjCPropertySynthesize(SourceLocation atLoc); DeclTy *ParseObjCPropertyDynamic(SourceLocation atLoc); - DeclTy *ParseObjCTryStmt(SourceLocation &atLoc); - DeclTy *ParseObjCThrowStmt(SourceLocation &atLoc); + DeclTy *ParseObjCTryStmt(SourceLocation atLoc); + DeclTy *ParseObjCThrowStmt(SourceLocation atLoc); IdentifierInfo *ParseObjCSelector(); // Definitions for Objective-c context sensitive keywords recognition. @@ -317,7 +317,7 @@ private: ExprResult ParseAssignmentExpression(); // Expr that doesn't include commas. ExprResult ParseExpressionWithLeadingIdentifier(const Token &Tok); - ExprResult ParseExpressionWithLeadingAt(SourceLocation &AtLoc); + ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc); ExprResult ParseAssignmentExprWithLeadingIdentifier(const Token &Tok); ExprResult ParseAssignmentExpressionWithLeadingStar(const Token &Tok); @@ -363,7 +363,7 @@ private: //===--------------------------------------------------------------------===// // Objective-C Expressions - ExprResult ParseObjCExpression(SourceLocation &AtLocation); + ExprResult ParseObjCExpression(SourceLocation AtLocation); ExprResult ParseObjCStringLiteral(); ExprResult ParseObjCEncodeExpression(); ExprResult ParseObjCProtocolExpression(); diff --git a/test/Parser/encode.m b/test/Parser/encode.m new file mode 100644 index 0000000000..ce12882ecf --- /dev/null +++ b/test/Parser/encode.m @@ -0,0 +1,8 @@ +// RUN: clang -fsyntax-only -verify %s + +int main(void) { + const char ch = @encode(char *)[2]; + char c = @encode(char *)[2] + 4; + return c; +} + diff --git a/test/Parser/objc-try-catch-1.m b/test/Parser/objc-try-catch-1.m index f4a1201c85..6a0acd13dc 100644 --- a/test/Parser/objc-try-catch-1.m +++ b/test/Parser/objc-try-catch-1.m @@ -1,3 +1,5 @@ +// RUN: clang -fsyntax-only -verify %s + void * proc(); @interface Frob @@ -22,7 +24,7 @@ void * foo() return proc(); } @catch (Frob* ex) { - @throw; + @throw 1,2; } @catch(...) { @throw (4,3,proc()); |