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 | 43c76c38fad88f70f21b07202fc090ad1480971d (patch) | |
tree | 0ffc1a38e17d17e045480f2fe98145fc6fe16461 /clang/lib/Parse/ParseObjc.cpp | |
parent | e76edcfc65a88687a2acd7d5f486f5502439fd2c (diff) | |
download | bcm5719-llvm-43c76c38fad88f70f21b07202fc090ad1480971d.tar.gz bcm5719-llvm-43c76c38fad88f70f21b07202fc090ad1480971d.zip |
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
Diffstat (limited to 'clang/lib/Parse/ParseObjc.cpp')
-rw-r--r-- | clang/lib/Parse/ParseObjc.cpp | 43 |
1 files changed, 18 insertions, 25 deletions
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 80de1b0ef30..81eacf6544c 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/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: |