зеркало из https://github.com/microsoft/clang.git
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
This commit is contained in:
Родитель
5951965a39
Коммит
b384d329e0
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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());
|
||||
|
|
Загрузка…
Ссылка в новой задаче