diff options
author | Chris Lattner <sabre@nondot.org> | 2008-10-20 07:00:43 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-10-20 07:00:43 +0000 |
commit | dd5b5f2bb73d037745940431b71eb98393d12d4f (patch) | |
tree | 817205093b14ee4a7dac684f76dd56fb120d4931 /lib/Parse/ParseObjc.cpp | |
parent | 2091a3f3292a2d0397894e3c47f71d2fe32b35ca (diff) |
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
Diffstat (limited to 'lib/Parse/ParseObjc.cpp')
-rw-r--r-- | lib/Parse/ParseObjc.cpp | 43 |
1 files changed, 18 insertions, 25 deletions
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<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: |