[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