[cfe-commits] r41667 - in /cfe/trunk: Parse/ParseObjc.cpp include/clang/Basic/TokenKinds.def include/clang/Parse/Parser.h

Fariborz Jahanian fjahanian at apple.com
Fri Aug 31 17:26:16 PDT 2007


Author: fjahanian
Date: Fri Aug 31 19:26:16 2007
New Revision: 41667

URL: http://llvm.org/viewvc/llvm-project?rev=41667&view=rev
Log:
Patch to parse @implementation prologue, method definitions,
objc2's @synthesize and @dynamic.

Modified:
    cfe/trunk/Parse/ParseObjc.cpp
    cfe/trunk/include/clang/Basic/TokenKinds.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=41667&r1=41666&r2=41667&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Fri Aug 31 19:26:16 2007
@@ -37,11 +37,15 @@
     case tok::objc_protocol:
       return ParseObjCAtProtocolDeclaration(AtLoc);
     case tok::objc_implementation:
-      return ParseObjCAtImplementationDeclaration();
+      return ParseObjCAtImplementationDeclaration(AtLoc);
     case tok::objc_end:
-      return ParseObjCAtEndDeclaration();
+      return ParseObjCAtEndDeclaration(AtLoc);
     case tok::objc_compatibility_alias:
       return ParseObjCAtAliasDeclaration();
+    case tok::objc_synthesize:
+      return ParseObjCPropertySynthesize(AtLoc);
+    case tok::objc_dynamic:
+      return ParseObjCPropertyDynamic(AtLoc);
     default:
       Diag(AtLoc, diag::err_unexpected_at);
       SkipUntil(tok::semi);
@@ -232,7 +236,7 @@
       }
     }
     if (Tok.getKind() == tok::minus || Tok.getKind() == tok::plus) {
-      ParseObjCMethodPrototype();
+      ParseObjCMethodPrototype(true);
       continue;
     }
     if (Tok.getKind() == tok::semi)
@@ -339,8 +343,9 @@
 }
 
 ///   objc-methodproto:
-///     objc-instance-method objc-method-decl objc-method-attributes[opt] ';'
-///     objc-class-method objc-method-decl objc-method-attributes[opt] ';'
+///     objc-instance-method objc-method-decl objc-method-attributes[opt] 
+///       ';'[opt]
+///     objc-class-method objc-method-decl objc-method-attributes[opt] ';'[opt]
 ///
 ///   objc-instance-method: '-'
 ///   objc-class-method: '+'
@@ -348,7 +353,7 @@
 ///   objc-method-attributes:         [OBJC2]
 ///     __attribute__((deprecated))
 ///
-void Parser::ParseObjCMethodPrototype() {
+void Parser::ParseObjCMethodPrototype(bool decl) {
   assert((Tok.getKind() == tok::minus || Tok.getKind() == tok::plus) && 
          "expected +/-");
 
@@ -362,8 +367,9 @@
   if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
     ParseAttributes();
     
-  // Consume the ';'.
-  ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "method proto");
+  if (decl)
+    // Consume the ';'.
+    ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "method proto");
 }
 
 ///   objc-selector:
@@ -700,12 +706,60 @@
 ///   objc-category-implementation-prologue:
 ///     @implementation identifier ( identifier )
 
-Parser::DeclTy *Parser::ParseObjCAtImplementationDeclaration() {
-  assert(0 && "Unimp");
+Parser::DeclTy *Parser::ParseObjCAtImplementationDeclaration(
+  SourceLocation atLoc) {
+  assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
+         "ParseObjCAtImplementationDeclaration(): Expected @implementation");
+  ConsumeToken(); // the "implementation" identifier
+  
+  if (Tok.getKind() != tok::identifier) {
+    Diag(Tok, diag::err_expected_ident); // missing class or category name.
+    return 0;
+  }
+  // We have a class or category name - consume it.
+  SourceLocation nameLoc = ConsumeToken(); // consume class or category name
+  
+  if (Tok.getKind() == tok::l_paren) { 
+    // we have a category implementation.
+    SourceLocation lparenLoc = ConsumeParen();
+    SourceLocation categoryLoc, rparenLoc;
+    IdentifierInfo *categoryId = 0;
+    
+    if (Tok.getKind() == tok::identifier) {
+      categoryId = Tok.getIdentifierInfo();
+      categoryLoc = ConsumeToken();
+    } else {
+      Diag(Tok, diag::err_expected_ident); // missing category name.
+      return 0;
+    }   
+    if (Tok.getKind() != tok::r_paren) {
+      Diag(Tok, diag::err_expected_rparen);
+      SkipUntil(tok::r_paren, false); // don't stop at ';'
+      return 0;
+    }
+    rparenLoc = ConsumeParen();
+    return 0;
+  }
+  // We have a class implementation
+  if (Tok.getKind() == tok::colon) {
+    // We have a super class
+    ConsumeToken();
+    if (Tok.getKind() != tok::identifier) {
+      Diag(Tok, diag::err_expected_ident); // missing super class name.
+      return 0;
+    }
+    ConsumeToken(); // Consume super class name
+  }
+  if (Tok.getKind() == tok::l_brace)
+    ParseObjCClassInstanceVariables(0/*FIXME*/); // we have ivars
+  
   return 0;
 }
-Parser::DeclTy *Parser::ParseObjCAtEndDeclaration() {
-  assert(0 && "Unimp");
+Parser::DeclTy *Parser::ParseObjCAtEndDeclaration(SourceLocation atLoc) {
+  assert(Tok.isObjCAtKeyword(tok::objc_end) &&
+         "ParseObjCAtEndDeclaration(): Expected @end");
+  ConsumeToken(); // the "end" identifier
+
   return 0;
 }
 Parser::DeclTy *Parser::ParseObjCAtAliasDeclaration() {
@@ -713,12 +767,104 @@
   return 0;
 }
 
+///   property-synthesis:
+///     @synthesize property-ivar-list ';'
+///
+///   property-ivar-list:
+///     property-ivar
+///     property-ivar-list ',' property-ivar
+///
+///   property-ivar:
+///     identifier
+///     identifier '=' identifier
+///
+Parser::DeclTy *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
+  assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
+         "ParseObjCPropertyDynamic(): Expected '@synthesize'");
+  SourceLocation loc = ConsumeToken(); // consume dynamic
+  if (Tok.getKind() != tok::identifier) {
+    Diag(Tok, diag::err_expected_ident);
+    return 0;
+  }
+  while (Tok.getKind() == tok::identifier) {
+    ConsumeToken(); // consume property name
+    if (Tok.getKind() == tok::equal) {
+      // property '=' ivar-name
+      ConsumeToken(); // consume '='
+      if (Tok.getKind() != tok::identifier) {
+        Diag(Tok, diag::err_expected_ident);
+        break;
+      }
+      ConsumeToken(); // consume ivar-name
+    }
+    if (Tok.getKind() != tok::comma)
+      break;
+    ConsumeToken(); // consume ','
+  }
+  if (Tok.getKind() != tok::semi)
+    Diag(Tok, diag::err_expected_semi_after, "@synthesize");
+  return 0;
+}
+
+///   property-dynamic:
+///     @dynamic  property-list
+///
+///   property-list:
+///     identifier
+///     property-list ',' identifier
+///
+Parser::DeclTy *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
+  assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
+         "ParseObjCPropertyDynamic(): Expected '@dynamic'");
+  SourceLocation loc = ConsumeToken(); // consume dynamic
+  if (Tok.getKind() != tok::identifier) {
+    Diag(Tok, diag::err_expected_ident);
+    return 0;
+  }
+  while (Tok.getKind() == tok::identifier) {
+    ConsumeToken(); // consume property name
+    if (Tok.getKind() != tok::comma)
+      break;
+    ConsumeToken(); // consume ','
+  }
+  if (Tok.getKind() != tok::semi)
+    Diag(Tok, diag::err_expected_semi_after, "@dynamic");
+  return 0;
+}
+
+///   objc-method-def: objc-methodproto ';'[opt] '{' body '}'
+///
 void Parser::ParseObjCInstanceMethodDefinition() {
-  assert(0 && "Parser::ParseObjCInstanceMethodDefinition():: Unimp");
+  assert(Tok.getKind() == tok::minus &&
+         "ParseObjCInstanceMethodDefinition(): Expected '-'");
+  ParseObjCMethodPrototype(false);
+  // parse optional ';'
+  if (Tok.getKind() == tok::semi)
+    ConsumeToken();
+
+  if (Tok.getKind() != tok::l_brace) {
+    Diag (Tok, diag::err_expected_lbrace);
+    return;
+  }
+    
+  StmtResult FnBody = ParseCompoundStatementBody();
 }
 
+///   objc-method-def: objc-methodproto ';'[opt] '{' body '}'
+///
 void Parser::ParseObjCClassMethodDefinition() {
-  assert(0 && "Parser::ParseObjCClassMethodDefinition():: Unimp");
+  assert(Tok.getKind() == tok::plus &&
+         "ParseObjCClassMethodDefinition(): Expected '+'");
+  ParseObjCMethodPrototype(false);
+  // parse optional ';'
+  if (Tok.getKind() == tok::semi)
+    ConsumeToken();
+  if (Tok.getKind() != tok::l_brace) {
+    Diag (Tok, diag::err_expected_lbrace);
+    return;
+  }
+  
+  StmtResult FnBody = ParseCompoundStatementBody();
 }
 
 Parser::ExprResult Parser::ParseObjCExpression() {

Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=41667&r1=41666&r2=41667&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Fri Aug 31 19:26:16 2007
@@ -347,11 +347,12 @@
 OBJC1_AT_KEYWORD(finally)
 OBJC1_AT_KEYWORD(synchronized)
 
-// I'm guessing this is an objc2 keyword, what are the others?
 OBJC2_AT_KEYWORD(property)
 OBJC2_AT_KEYWORD(package)
 OBJC2_AT_KEYWORD(required)
 OBJC2_AT_KEYWORD(optional)
+OBJC2_AT_KEYWORD(synthesize)
+OBJC2_AT_KEYWORD(dynamic)
 
 // TODO: What to do about context-sensitive keywords like:
 //       bycopy/byref/in/inout/oneway/out?

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=41667&r1=41666&r2=41667&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Aug 31 19:26:16 2007
@@ -262,9 +262,11 @@
   bool ParseObjCProtocolReferences();
   void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl);
   DeclTy *ParseObjCAtProtocolDeclaration(SourceLocation atLoc);
-  DeclTy *ParseObjCAtImplementationDeclaration();
-  DeclTy *ParseObjCAtEndDeclaration();
+  DeclTy *ParseObjCAtImplementationDeclaration(SourceLocation atLoc);
+  DeclTy *ParseObjCAtEndDeclaration(SourceLocation atLoc);
   DeclTy *ParseObjCAtAliasDeclaration();
+  DeclTy *ParseObjCPropertySynthesize(SourceLocation atLoc);
+  DeclTy *ParseObjCPropertyDynamic(SourceLocation atLoc);
   
   IdentifierInfo *ParseObjCSelector();
   // Definitions for Objective-c context sensitive keywords recognition.
@@ -284,7 +286,7 @@
 
   void ParseObjCTypeName();
   void ParseObjCMethodRequirement();
-  void ParseObjCMethodPrototype();
+  void ParseObjCMethodPrototype(bool decl);
   void ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation mLoc);
   void ParseObjCPropertyAttribute(DeclTy *interfaceDecl);
   void ParseObjCPropertyDecl(DeclTy *interfaceDecl);





More information about the cfe-commits mailing list