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;
          ^

llvm-svn: 57809
This commit is contained in:
Chris Lattner 2008-10-20 07:00:43 +00:00
parent e76edcfc65
commit 43c76c38fa
1 changed files with 18 additions and 25 deletions

View File

@ -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<FieldDeclarator, 8> 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: