From: Chris Lattner Date: Mon, 20 Oct 2008 06:10:06 +0000 (+0000) Subject: refactor a bunch of code: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bc662afa1cb9b61cb1e7808bb1463dd6291b8095;p=clang refactor a bunch of code: Check for @end in ParseObjCInterfaceDeclList instead of in each caller Handle @required and @optional with the same code Add some fixmes about some apparently objc2 code that is being accepted in objc1. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57803 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index f409df465b..3ec0058555 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -430,10 +430,8 @@ DIAG(warn_objc_property_default_assign_on_object, WARNING, "default property attribute 'assign' not appropriate for non-gc object") DIAG(err_objc_property_requires_object, ERROR, "property with '%0' attribute must be of object type") -DIAG(err_objc_protocol_required, ERROR, - "@required may be specified in protocols only") -DIAG(err_objc_protocol_optional, ERROR, - "@optional may be specified in protocols only") +DIAG(err_objc_directive_only_in_protocol, ERROR, + "directive may only be specified in protocols only") DIAG(err_missing_catch_finally, ERROR, "@try statement without a @catch and @finally clause") DIAG(err_objc_concat_string, ERROR, diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 52d52bde7e..6369817ad5 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -163,14 +163,7 @@ Parser::DeclTy *Parser::ParseObjCAtInterfaceDeclaration( EndProtoLoc); ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword); - - // The @ sign was already consumed by ParseObjCInterfaceDeclList(). - if (Tok.isObjCAtKeyword(tok::objc_end)) { - ConsumeToken(); // the "end" identifier - return CategoryType; - } - Diag(Tok, diag::err_objc_missing_end); - return 0; + return CategoryType; } // Parse a class interface. IdentifierInfo *superClassId = 0; @@ -202,14 +195,7 @@ Parser::DeclTy *Parser::ParseObjCAtInterfaceDeclaration( ParseObjCClassInstanceVariables(ClsType, atLoc); ParseObjCInterfaceDeclList(ClsType, tok::objc_interface); - - // The @ sign was already consumed by ParseObjCInterfaceDeclList(). - if (Tok.isObjCAtKeyword(tok::objc_end)) { - ConsumeToken(); // the "end" identifier - return ClsType; - } - Diag(Tok, diag::err_objc_missing_end); - return 0; + return ClsType; } /// constructSetterName - Return the setter name for the given @@ -246,8 +232,9 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, llvm::SmallVector allMethods; llvm::SmallVector allProperties; tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword; - SourceLocation AtEndLoc; + SourceLocation AtEndLoc; + while (1) { // If this is a method prototype, parse it. if (Tok.is(tok::minus) || Tok.is(tok::plus)) { @@ -266,8 +253,7 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, continue; } - // If we got to the end of the file, pretend that we saw an @end. - // FIXME: Should this be a warning? + // If we got to the end of the file, exit the loop. if (Tok.is(tok::eof)) break; @@ -286,37 +272,34 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, if (DirectiveKind == tok::objc_end) { // @end -> terminate list AtEndLoc = AtLoc; break; - } + } + // Eat the identifier. + ConsumeToken(); + switch (DirectiveKind) { default: + // FIXME: If someone forgets an @end on a protocol, this loop will + // continue to eat up tons of stuff and spew lots of nonsense errors. It + // would probably be better to bail out if we saw an @class or @interface + // or something like that. Diag(Tok, diag::err_objc_illegal_interface_qual); - ConsumeToken(); - // Skip until we see an @ or } or ; + // Skip until we see an '@' or '}' or ';'. SkipUntil(tok::r_brace, tok::at); break; case tok::objc_required: - ConsumeToken(); - // This is only valid on protocols. - if (contextKey != tok::objc_protocol) - Diag(AtLoc, diag::err_objc_protocol_required); - else - MethodImplKind = tok::objc_required; - break; - case tok::objc_optional: - ConsumeToken(); // This is only valid on protocols. + // FIXME: Should this check for ObjC2 being enabled? if (contextKey != tok::objc_protocol) - Diag(AtLoc, diag::err_objc_protocol_optional); + Diag(AtLoc, diag::err_objc_directive_only_in_protocol); else - MethodImplKind = tok::objc_optional; + MethodImplKind = DirectiveKind; break; case tok::objc_property: ObjCDeclSpec OCDS; - ConsumeToken(); // the "property" identifier // Parse property attribute list, if any. if (Tok.is(tok::l_paren)) { // property has attribute list. @@ -356,9 +339,16 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, break; } } + + // We break out of the big loop in two cases: when we see @end or when we see + // EOF. In the former case, eat the @end. In the later case, emit an error. + if (Tok.isObjCAtKeyword(tok::objc_end)) + ConsumeToken(); // the "end" identifier + else + Diag(Tok, diag::err_objc_missing_end); + // Insert collected methods declarations into the @interface object. - // FIXME: This passes in an invalid SourceLocation for AtEndLoc when EOF is - // hit. + // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit. Actions.ActOnAtEnd(AtEndLoc, interfaceDecl, allMethods.empty() ? 0 : &allMethods[0], allMethods.size(), @@ -1006,14 +996,7 @@ Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, &ProtocolRefs[0], ProtocolRefs.size(), EndProtoLoc, attrList); ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol); - - // The @ sign was already consumed by ParseObjCInterfaceDeclList(). - if (Tok.isObjCAtKeyword(tok::objc_end)) { - ConsumeToken(); // the "end" identifier - return ProtoType; - } - Diag(Tok, diag::err_objc_missing_end); - return 0; + return ProtoType; } /// objc-implementation: diff --git a/test/SemaObjC/protocol-test-1.m b/test/SemaObjC/protocol-test-1.m index 6fb28b533c..c8e4080c5e 100644 --- a/test/SemaObjC/protocol-test-1.m +++ b/test/SemaObjC/protocol-test-1.m @@ -9,11 +9,11 @@ @end @interface INTF1 -@required // expected-error {{@required may be specified in protocols only}} +@required // expected-error {{directive may only be specified in protocols only}} - (int) FooBar; - (int) FooBar1; - (int) FooBar2; -@optional // expected-error {{@optional may be specified in protocols only}} +@optional // expected-error {{directive may only be specified in protocols only}} + (int) C; - (int)I;