From: Chris Lattner Date: Mon, 20 Oct 2008 05:57:40 +0000 (+0000) Subject: fix some minor error recovery bugs in ParseObjCInterfaceDeclList X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a2449b2bf739545494241e189b59587d5ca5c2c1;p=clang fix some minor error recovery bugs in ParseObjCInterfaceDeclList where it would reject @required in non-protocols, but then go ahead and tag methods with required anyway. Instead, if we see this in something other than a protocol, just ignore the request. Also, improve error recovery a bit when we see something bogus inside an interface. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57798 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 16fab37e48..52d52bde7e 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -281,24 +281,40 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, // Otherwise, we have an @ directive, eat the @. SourceLocation AtLoc = ConsumeToken(); // the "@" - tok::ObjCKeywordKind ocKind = Tok.getObjCKeywordID(); + tok::ObjCKeywordKind DirectiveKind = Tok.getObjCKeywordID(); - if (ocKind == tok::objc_end) { // @end -> terminate list + if (DirectiveKind == tok::objc_end) { // @end -> terminate list AtEndLoc = AtLoc; break; } - if (ocKind == tok::objc_required) { // protocols only + switch (DirectiveKind) { + default: + Diag(Tok, diag::err_objc_illegal_interface_qual); + ConsumeToken(); + // Skip until we see an @ or } or ; + SkipUntil(tok::r_brace, tok::at); + break; + + case tok::objc_required: ConsumeToken(); - MethodImplKind = ocKind; + // This is only valid on protocols. if (contextKey != tok::objc_protocol) Diag(AtLoc, diag::err_objc_protocol_required); - } else if (ocKind == tok::objc_optional) { // protocols only + else + MethodImplKind = tok::objc_required; + break; + + case tok::objc_optional: ConsumeToken(); - MethodImplKind = ocKind; + // This is only valid on protocols. if (contextKey != tok::objc_protocol) Diag(AtLoc, diag::err_objc_protocol_optional); - } else if (ocKind == tok::objc_property) { + else + MethodImplKind = tok::objc_optional; + break; + + case tok::objc_property: ObjCDeclSpec OCDS; ConsumeToken(); // the "property" identifier // Parse property attribute list, if any. @@ -337,13 +353,12 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, MethodImplKind); allProperties.push_back(Property); } - continue; - } else { - Diag(Tok, diag::err_objc_illegal_interface_qual); - ConsumeToken(); + break; } } - /// Insert collected methods declarations into the @interface object. + // Insert collected methods declarations into the @interface object. + // FIXME: This passes in an invalid SourceLocation for AtEndLoc when EOF is + // hit. Actions.ActOnAtEnd(AtEndLoc, interfaceDecl, allMethods.empty() ? 0 : &allMethods[0], allMethods.size(),