From cd9f4b31c4fe5b77b5519cc17b4583fab912bad1 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 20 Oct 2008 07:15:22 +0000 Subject: [PATCH] More property attribute recovery improvements. Instead of this: crash.m:8:12: error: type name requires a specifier or qualifier @property (readonlyx, getter=isAwesome) int _awesome; ^ crash.m:8:29: error: expected ';' at end of declaration list @property (readonlyx, getter=isAwesome) int _awesome; ^ crash.m:8:39: error: expected identifier or '(' @property (readonlyx, getter=isAwesome) int _awesome; ^ we now get: crash.m:8:12: error: unknown property attribute 'readonlyx' @property (readonlyx, getter=isAwesome) int _awesome; ^ Also, we can eliminate isObjCPropertyAttribute now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57811 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticKinds.def | 4 ++-- include/clang/Parse/Parser.h | 1 - lib/Parse/ParseObjc.cpp | 29 +++++++++++-------------- test/SemaObjC/property-9.m | 6 +++++ 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 09eb5d98e1..89bf0ce305 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -419,9 +419,9 @@ DIAG(err_objc_illegal_interface_qual, ERROR, DIAG(err_objc_expected_equal, ERROR, "setter/getter expects '=' followed by name") DIAG(err_objc_property_requires_field_name, ERROR, - "@property requires fields to be named") + "property requires fields to be named") DIAG(err_objc_expected_property_attr, ERROR, - "unknown property attribute detected") + "unknown property attribute '%0'") DIAG(err_objc_unexpected_attr, ERROR, "prefix attribute must be followed by an interface or protocol") DIAG(err_objc_property_attr_mutually_exclusive, ERROR, diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 380f3d2f9b..c47366f431 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -396,7 +396,6 @@ private: objc_readwrite, objc_retain, objc_copy, objc_nonatomic, objc_NumAttrs }; IdentifierInfo *ObjCPropertyAttrs[objc_NumAttrs]; - bool isObjCPropertyAttribute(); bool isTokIdentifier_in() const; diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 81eacf6544..c8544007c3 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -377,7 +377,7 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) { SourceLocation LHSLoc = ConsumeParen(); // consume '(' - while (isObjCPropertyAttribute()) { + while (1) { const IdentifierInfo *II = Tok.getIdentifierInfo(); // getter/setter require extra treatment. if (II == ObjCPropertyAttrs[objc_getter] || @@ -393,7 +393,7 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) { loc = ConsumeToken(); // consume method name if (Tok.isNot(tok::colon)) { Diag(loc, diag::err_expected_colon); - SkipUntil(tok::r_paren,true,true); + SkipUntil(tok::r_paren); return; } } else { @@ -402,13 +402,13 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) { } } else { Diag(loc, diag::err_expected_ident); - SkipUntil(tok::r_paren,true,true); + SkipUntil(tok::r_paren); return; } } else { Diag(loc, diag::err_objc_expected_equal); - SkipUntil(tok::r_paren,true,true); + SkipUntil(tok::r_paren); return; } } else if (II == ObjCPropertyAttrs[objc_readonly]) @@ -423,6 +423,15 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) { DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_copy); else if (II == ObjCPropertyAttrs[objc_nonatomic]) DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nonatomic); + else if (II) { + Diag(Tok.getLocation(), diag::err_objc_expected_property_attr, + II->getName()); + SkipUntil(tok::r_paren); + return; + } else { + MatchRHSPunctuation(tok::r_paren, LHSLoc); + return; + } ConsumeToken(); // consume last attribute token if (Tok.is(tok::comma)) { @@ -550,18 +559,6 @@ IdentifierInfo *Parser::ParseObjCSelector(SourceLocation &SelectorLoc) { } } -/// property-attrlist: one of -/// readonly getter setter assign retain copy nonatomic -/// -bool Parser::isObjCPropertyAttribute() { - if (Tok.is(tok::identifier)) { - const IdentifierInfo *II = Tok.getIdentifierInfo(); - for (unsigned i = 0; i < objc_NumAttrs; ++i) - if (II == ObjCPropertyAttrs[i]) return true; - } - return false; -} - /// objc-for-collection-in: 'in' /// bool Parser::isTokIdentifier_in() const { diff --git a/test/SemaObjC/property-9.m b/test/SemaObjC/property-9.m index 4aa3515c4b..a1f29e6f98 100644 --- a/test/SemaObjC/property-9.m +++ b/test/SemaObjC/property-9.m @@ -53,6 +53,12 @@ typedef signed char BOOL; @property (readonly getter=isAwesome) // expected-error {{error: expected ')'}} \ // expected-error {{to match this '('}} int _awesome; +@property (readonlyx) // expected-error {{unknown property attribute 'readonlyx'}} + int _awesome2; + +@property (+) // expected-error {{error: expected ')'}} \ + // expected-error {{to match this '('}} + int _awesome3; @end -- 2.40.0