From: Chris Lattner Date: Mon, 20 Oct 2008 07:00:43 +0000 (+0000) Subject: significantly simplify and clean up error recovery in X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dd5b5f2bb73d037745940431b71eb98393d12d4f;p=clang significantly simplify and clean up error recovery in ParseObjCPropertyAttribute. Before, on this code (where a comma was forgotten): @property (readonly getter=isAwesome) int _awesome; we emitted: crash.m:9:11: error: expected ')' @property (readonly getter=isAwesome) int _awesome; ^ crash.m:9:37: error: type name requires a specifier or qualifier @property (readonly getter=isAwesome) int _awesome; ^ crash.m:9:37: error: expected identifier or '(' crash.m:9:37: error: expected ';' at end of declaration list crash.m:9:1: error: @property requires fields to be named @property (readonly getter=isAwesome) int _awesome; ^ now we emit: crash.m:9:21: error: expected ')' @property (readonly getter=isAwesome) int _awesome; ^ crash.m:9:11: error: to match this '(' @property (readonly getter=isAwesome) int _awesome; ^ git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57809 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 80de1b0ef3..81eacf6544 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -301,10 +301,9 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, case tok::objc_property: ObjCDeclSpec OCDS; // Parse property attribute list, if any. - if (Tok.is(tok::l_paren)) { - // property has attribute list. + if (Tok.is(tok::l_paren)) ParseObjCPropertyAttribute(OCDS); - } + // Parse all the comma separated declarators. DeclSpec DS; llvm::SmallVector FieldDeclarators; @@ -376,7 +375,8 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, /// nonatomic /// void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) { - SourceLocation loc = ConsumeParen(); // consume '(' + SourceLocation LHSLoc = ConsumeParen(); // consume '(' + while (isObjCPropertyAttribute()) { const IdentifierInfo *II = Tok.getIdentifierInfo(); // getter/setter require extra treatment. @@ -394,28 +394,24 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) { if (Tok.isNot(tok::colon)) { Diag(loc, diag::err_expected_colon); SkipUntil(tok::r_paren,true,true); - break; + return; } - } - else { + } else { DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_getter); DS.setGetterName(Tok.getIdentifierInfo()); } - } - else { + } else { Diag(loc, diag::err_expected_ident); SkipUntil(tok::r_paren,true,true); - break; + return; } } else { Diag(loc, diag::err_objc_expected_equal); SkipUntil(tok::r_paren,true,true); - break; + return; } - } - - else if (II == ObjCPropertyAttrs[objc_readonly]) + } else if (II == ObjCPropertyAttrs[objc_readonly]) DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readonly); else if (II == ObjCPropertyAttrs[objc_assign]) DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_assign); @@ -430,21 +426,18 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) { ConsumeToken(); // consume last attribute token if (Tok.is(tok::comma)) { - loc = ConsumeToken(); + ConsumeToken(); continue; } - if (Tok.is(tok::r_paren)) - break; - Diag(loc, diag::err_expected_rparen); - SkipUntil(tok::semi); + + if (Tok.is(tok::r_paren)) { + ConsumeParen(); + return; + } + + MatchRHSPunctuation(tok::r_paren, LHSLoc); return; } - if (Tok.is(tok::r_paren)) - ConsumeParen(); - else { - Diag(loc, diag::err_objc_expected_property_attr); - SkipUntil(tok::r_paren); // recover from error inside attribute list - } } /// objc-method-proto: