summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseObjc.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-10-20 07:00:43 +0000
committerChris Lattner <sabre@nondot.org>2008-10-20 07:00:43 +0000
commit43c76c38fad88f70f21b07202fc090ad1480971d (patch)
tree0ffc1a38e17d17e045480f2fe98145fc6fe16461 /clang/lib/Parse/ParseObjc.cpp
parente76edcfc65a88687a2acd7d5f486f5502439fd2c (diff)
downloadbcm5719-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.cpp43
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:
OpenPOWER on IntegriCloud