forked from OSchip/llvm-project
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:
parent
e76edcfc65
commit
43c76c38fa
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue