[cfe-commits] r41644 - in /cfe/trunk: Parse/ParseObjc.cpp Parse/Parser.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Parser.h
Fariborz Jahanian
fjahanian at apple.com
Fri Aug 31 09:11:32 PDT 2007
Author: fjahanian
Date: Fri Aug 31 11:11:31 2007
New Revision: 41644
URL: http://llvm.org/viewvc/llvm-project?rev=41644&view=rev
Log:
Author: F. Jahanian
Log:
Implement parsing of objective-c's new @property declaration.
Modified:
include/clang/Basic/DiagnosticKinds.def
include/clang/Parse/Parser.h
Parse/ParseObjc.cpp
Parse/Parser.cpp
Modified:
cfe/trunk/Parse/ParseObjc.cpp
cfe/trunk/Parse/Parser.cpp
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/include/clang/Parse/Parser.h
Modified: cfe/trunk/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseObjc.cpp?rev=41644&r1=41643&r2=41644&view=diff
==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Fri Aug 31 11:11:31 2007
@@ -224,7 +224,7 @@
ConsumeToken();
continue;
} else if (ocKind == tok::objc_property) {
- ParseObjCPropertyDecl(AtLoc);
+ ParseObjCPropertyDecl(0/*FIXME*/);
continue;
} else {
Diag(Tok, diag::err_objc_illegal_interface_qual);
@@ -246,8 +246,96 @@
}
}
-void Parser::ParseObjCPropertyDecl(SourceLocation atLoc) {
- assert(0 && "Unimp");
+/// Parse property attribute declarations.
+///
+/// property-attr-decl: '(' property-attrlist ')'
+/// property-attrlist:
+/// property-attribute
+/// property-attrlist ',' property-attribute
+/// property-attribute:
+/// getter '=' identifier
+/// setter '=' identifier ':'
+/// readonly
+/// readwrite
+/// assign
+/// retain
+/// copy
+/// nonatomic
+///
+void Parser::ParseObjCPropertyAttribute (DeclTy *interfaceDecl) {
+ SourceLocation loc = ConsumeParen(); // consume '('
+ while (isObjCPropertyAttribute()) {
+ const IdentifierInfo *II = Tok.getIdentifierInfo();
+ // getter/setter require extra treatment.
+ if (II == ObjcPropertyAttrs[objc_getter] ||
+ II == ObjcPropertyAttrs[objc_setter]) {
+ // skip getter/setter part.
+ SourceLocation loc = ConsumeToken();
+ if (Tok.getKind() == tok::equal) {
+ loc = ConsumeToken();
+ if (Tok.getKind() == tok::identifier) {
+ if (II == ObjcPropertyAttrs[objc_setter]) {
+ loc = ConsumeToken(); // consume method name
+ if (Tok.getKind() != tok::colon) {
+ Diag(loc, diag::err_expected_colon);
+ SkipUntil(tok::r_paren,true,true);
+ break;
+ }
+ }
+ }
+ else {
+ Diag(loc, diag::err_expected_ident);
+ SkipUntil(tok::r_paren,true,true);
+ break;
+ }
+ }
+ else {
+ Diag(loc, diag::err_objc_expected_equal);
+ SkipUntil(tok::r_paren,true,true);
+ break;
+ }
+ }
+ ConsumeToken(); // consume last attribute token
+ if (Tok.getKind() == tok::comma) {
+ loc = ConsumeToken();
+ continue;
+ }
+ if (Tok.getKind() == tok::r_paren)
+ break;
+ Diag(loc, diag::err_expected_rparen);
+ SkipUntil(tok::semi);
+ return;
+ }
+ if (Tok.getKind() == tok::r_paren)
+ ConsumeParen();
+ else {
+ Diag(loc, diag::err_objc_expected_property_attr);
+ SkipUntil(tok::r_paren); // recover from error inside attribute list
+ }
+}
+
+/// Main routine to parse property declaration.
+///
+/// @property property-attr-decl[opt] property-component-decl ';'
+///
+void Parser::ParseObjCPropertyDecl(DeclTy *interfaceDecl) {
+ assert(Tok.isObjCAtKeyword(tok::objc_property) &&
+ "ParseObjCPropertyDecl(): Expected @property");
+ ConsumeToken(); // the "property" identifier
+ // Parse property attribute list, if any.
+ if (Tok.getKind() == tok::l_paren) {
+ // property has attribute list.
+ ParseObjCPropertyAttribute(0/*FIXME*/);
+ }
+ // Parse declaration portion of @property.
+ llvm::SmallVector<DeclTy*, 32> PropertyDecls;
+ ParseStructDeclaration(interfaceDecl, PropertyDecls);
+ if (Tok.getKind() == tok::semi)
+ ConsumeToken();
+ else {
+ Diag(Tok, diag::err_expected_semi_decl_list);
+ SkipUntil(tok::r_brace, true, true);
+ }
}
/// objc-methodproto:
@@ -312,6 +400,18 @@
return false;
}
+/// property-attrlist: one of
+/// readonly getter setter assign retain copy nonatomic
+///
+bool Parser::isObjCPropertyAttribute() {
+ if (Tok.getKind() == tok::identifier) {
+ const IdentifierInfo *II = Tok.getIdentifierInfo();
+ for (unsigned i = 0; i < objc_NumAttrs; ++i)
+ if (II == ObjcPropertyAttrs[i]) return true;
+ }
+ return false;
+}
+
/// objc-type-name:
/// '(' objc-type-qualifiers[opt] type-name ')'
/// '(' objc-type-qualifiers[opt] ')'
Modified: cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/Parser.cpp?rev=41644&r1=41643&r2=41644&view=diff
==============================================================================
--- cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/trunk/Parse/Parser.cpp Fri Aug 31 11:11:31 2007
@@ -258,6 +258,18 @@
ObjcTypeQuals[objc_bycopy] = &PP.getIdentifierTable().get("bycopy");
ObjcTypeQuals[objc_byref] = &PP.getIdentifierTable().get("byref");
}
+ if (getLang().ObjC2) {
+ ObjcPropertyAttrs[objc_readonly] = &PP.getIdentifierTable().get("readonly");
+ ObjcPropertyAttrs[objc_getter] = &PP.getIdentifierTable().get("getter");
+ ObjcPropertyAttrs[objc_setter] = &PP.getIdentifierTable().get("setter");
+ ObjcPropertyAttrs[objc_assign] = &PP.getIdentifierTable().get("assign");
+ ObjcPropertyAttrs[objc_readwrite] =
+ &PP.getIdentifierTable().get("readwrite");
+ ObjcPropertyAttrs[objc_retain] = &PP.getIdentifierTable().get("retain");
+ ObjcPropertyAttrs[objc_copy] = &PP.getIdentifierTable().get("copy");
+ ObjcPropertyAttrs[objc_nonatomic] =
+ &PP.getIdentifierTable().get("nonatomic");
+ }
}
/// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=41644&r1=41643&r2=41644&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Fri Aug 31 11:11:31 2007
@@ -399,6 +399,10 @@
"illegal visibility specification")
DIAG(err_objc_illegal_interface_qual, ERROR,
"illegal interface qualifier")
+DIAG(err_objc_expected_equal, ERROR,
+ "setter/getter expects '=' followed by name")
+DIAG(err_objc_expected_property_attr, ERROR,
+ "unknown property attribute detected")
//===----------------------------------------------------------------------===//
// Semantic Analysis
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=41644&r1=41643&r2=41644&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Aug 31 11:11:31 2007
@@ -274,11 +274,20 @@
};
IdentifierInfo *ObjcTypeQuals[objc_NumQuals];
bool isObjCTypeQualifier();
+ // Definitions for ObjC2's @property attributes.
+ enum ObjCPropertyAttr {
+ objc_readonly=0, objc_getter, objc_setter, objc_assign,
+ objc_readwrite, objc_retain, objc_copy, objc_nonatomic, objc_NumAttrs
+ };
+ IdentifierInfo *ObjcPropertyAttrs[objc_NumAttrs];
+ bool isObjCPropertyAttribute();
+
void ParseObjCTypeName();
void ParseObjCMethodRequirement();
void ParseObjCMethodPrototype();
void ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation mLoc);
- void ParseObjCPropertyDecl(SourceLocation atLoc);
+ void ParseObjCPropertyAttribute(DeclTy *interfaceDecl);
+ void ParseObjCPropertyDecl(DeclTy *interfaceDecl);
void ParseObjCInstanceMethodDefinition();
void ParseObjCClassMethodDefinition();
More information about the cfe-commits
mailing list