[cfe-commits] r41300 - in /cfe/trunk: Parse/ParseObjc.cpp Parse/Parser.cpp include/clang/Parse/Parser.h

Steve Naroff snaroff at apple.com
Wed Aug 22 15:17:26 PDT 2007


Author: snaroff
Date: Wed Aug 22 17:17:26 2007
New Revision: 41300

URL: http://llvm.org/viewvc/llvm-project?rev=41300&view=rev
Log:

Add support for parsing protocols.

Now we can parse quite a bit of "Foundation.h" (a couple bugs remain).

Modified:
    cfe/trunk/Parse/ParseObjc.cpp
    cfe/trunk/Parse/Parser.cpp
    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=41300&r1=41299&r2=41300&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Wed Aug 22 17:17:26 2007
@@ -36,7 +36,7 @@
     case tok::objc_interface:
       return ParseObjCAtInterfaceDeclaration(AtLoc);
     case tok::objc_protocol:
-      return ParseObjCAtProtocolDeclaration();
+      return ParseObjCAtProtocolDeclaration(AtLoc);
     case tok::objc_implementation:
       return ParseObjCAtImplementationDeclaration();
     case tok::objc_end:
@@ -64,7 +64,6 @@
       SkipUntil(tok::semi);
       return 0;
     }
-    
     ClassNames.push_back(Tok.getIdentifierInfo());
     ConsumeToken();
     
@@ -112,7 +111,8 @@
 ///
 Parser::DeclTy *Parser::ParseObjCAtInterfaceDeclaration(
   SourceLocation atLoc, AttributeList *attrList) {
-  assert(Tok.getIdentifierInfo()->getObjCKeywordID() == tok::objc_interface &&
+  assert((Tok.getKind() == tok::identifier &&
+          Tok.getIdentifierInfo()->getObjCKeywordID() == tok::objc_interface) &&
          "ParseObjCAtInterfaceDeclaration(): Expected @interface");
   ConsumeToken(); // the "interface" identifier
   
@@ -121,7 +121,7 @@
     return 0;
   }
   // We have a class or category name - consume it.
-  // IdentifierInfo *nameId = Tok.getIdentifierInfo();
+  IdentifierInfo *nameId = Tok.getIdentifierInfo();
   SourceLocation nameLoc = ConsumeToken();
   
   if (Tok.getKind() == tok::l_paren) { // we have a category
@@ -162,6 +162,11 @@
   // Parse a class interface.
   IdentifierInfo *superClassId = 0;
   SourceLocation superClassLoc;
+
+  // FIXME: temporary hack to grok class names (until we have sema support).
+  llvm::SmallVector<IdentifierInfo *, 1> ClassName;
+  ClassName.push_back(nameId);
+  Actions.ParsedObjcClassDeclaration(CurScope, &ClassName[0], 1);
   
   if (Tok.getKind() == tok::colon) { // a super class is specified.
     ConsumeToken();
@@ -313,9 +318,9 @@
   SourceLocation LParenLoc = ConsumeParen(), RParenLoc;
   
   if (isTypeSpecifierQualifier()) {
-    TypeTy *Ty = ParseTypeName();
-
-    assert(Ty && "Parser::ParseObjCTypeName(): missing type");
+    //TypeTy *Ty = ParseTypeName();
+    //assert(Ty && "Parser::ParseObjCTypeName(): missing type");
+    ParseTypeName(); // FIXME: when sema support is added.
   }
   if (Tok.getKind() != tok::r_paren) {
     MatchRHSPunctuation(tok::r_paren, LParenLoc);
@@ -331,14 +336,14 @@
 ///     objc-type-name objc-keyword-selector objc-parmlist[opt]
 ///
 ///   objc-keyword-selector:
-///     objc-keyword-decl
+///     objc-keyword-decl 
 ///     objc-keyword-selector objc-keyword-decl
 ///
 ///   objc-keyword-decl:
-///     objc-selector ':' objc-type-name identifier
-///     objc-selector ':' identifier
-///     ':' objc-type-name identifier
-///     ':' identifier
+///     objc-selector ':' objc-type-name objc-keyword-attributes[opt] identifier
+///     objc-selector ':' objc-keyword-attributes[opt] identifier
+///     ':' objc-type-name objc-keyword-attributes[opt] identifier
+///     ':' objc-keyword-attributes[opt] identifier
 ///
 ///   objc-parmlist:
 ///     objc-parms objc-ellipsis[opt]
@@ -349,6 +354,9 @@
 ///   objc-ellipsis:
 ///     , ...
 ///
+///   objc-keyword-attributes:         [OBJC2]
+///     __attribute__((unused))
+///
 void Parser::ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation mLoc) {
 
   // Parse the return type.
@@ -367,6 +375,11 @@
       ConsumeToken(); // Eat the ':'.
       if (Tok.getKind() == tok::l_paren) // Parse the argument type.
         ParseObjCTypeName();
+
+      // If attributes exist before the argument name, parse them.
+      if (Tok.getKind() == tok::kw___attribute)
+        ParseAttributes();
+
       if (Tok.getKind() != tok::identifier) {
         Diag(Tok, diag::err_expected_ident); // missing argument name.
         break;
@@ -510,8 +523,61 @@
 ///   identifier-list ;": objc-methodprotolist may not start with a
 ///   semicolon in the first alternative if objc-protocol-refs are omitted.
 
-Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration() {
-  assert(0 && "Unimp");
+Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc) {
+  assert((Tok.getKind() == tok::identifier &&
+          Tok.getIdentifierInfo()->getObjCKeywordID() == tok::objc_protocol) &&
+         "ParseObjCAtProtocolDeclaration(): Expected @protocol");
+  ConsumeToken(); // the "protocol" identifier
+  
+  if (Tok.getKind() != tok::identifier) {
+    Diag(Tok, diag::err_expected_ident); // missing protocol name.
+    return 0;
+  }
+  // Save the protocol name, then consume it.
+  IdentifierInfo *protocolName = Tok.getIdentifierInfo();
+  SourceLocation nameLoc = ConsumeToken();
+  
+  if (Tok.getKind() == tok::semi) { // forward declaration.
+    ConsumeToken();
+    return 0; // FIXME: add protocolName
+  }
+  if (Tok.getKind() == tok::comma) { // list of forward declarations.
+    // Parse the list of forward declarations.
+    llvm::SmallVector<IdentifierInfo *, 8> ProtocolRefs;
+    ProtocolRefs.push_back(protocolName);
+    
+    while (1) {
+      ConsumeToken(); // the ','
+      if (Tok.getKind() != tok::identifier) {
+        Diag(Tok, diag::err_expected_ident);
+        SkipUntil(tok::semi);
+        return 0;
+      }
+      ProtocolRefs.push_back(Tok.getIdentifierInfo());
+      ConsumeToken(); // the identifier
+      
+      if (Tok.getKind() != tok::comma)
+        break;
+    }
+    // Consume the ';'.
+    if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol"))
+      return 0;
+    return 0; // FIXME
+  }
+  // Last, and definitely not least, parse a protocol declaration.
+  if (Tok.getKind() == tok::less) {
+    if (ParseObjCProtocolReferences())
+      return 0;
+  }
+  ParseObjCInterfaceDeclList(0/*FIXME*/);
+
+  // The @ sign was already consumed by ParseObjCInterfaceDeclList().
+  if (Tok.getKind() == tok::identifier &&
+      Tok.getIdentifierInfo()->getObjCKeywordID() == tok::objc_end) {
+    ConsumeToken(); // the "end" identifier
+    return 0;
+  }
+  Diag(Tok, diag::err_objc_missing_end);
   return 0;
 }
 
@@ -539,12 +605,12 @@
   return 0;
 }
 
-void Parser::ParseObjCInstanceMethodDeclaration() {
-  assert(0 && "Unimp");
+void Parser::ParseObjCInstanceMethodDefinition() {
+  assert(0 && "Parser::ParseObjCInstanceMethodDefinition():: Unimp");
 }
 
-void Parser::ParseObjCClassMethodDeclaration() {
-  assert(0 && "Unimp");
+void Parser::ParseObjCClassMethodDefinition() {
+  assert(0 && "Parser::ParseObjCClassMethodDefinition():: Unimp");
 }
 
 Parser::ExprResult Parser::ParseObjCExpression() {

Modified: cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/Parser.cpp?rev=41300&r1=41299&r2=41300&view=diff

==============================================================================
--- cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/trunk/Parse/Parser.cpp Wed Aug 22 17:17:26 2007
@@ -323,7 +323,7 @@
     return 0;
   case tok::minus:
     if (getLang().ObjC1) {
-      ParseObjCInstanceMethodDeclaration();
+      ParseObjCInstanceMethodDefinition();
     } else {
       Diag(Tok, diag::err_expected_external_declaration);
       ConsumeToken();
@@ -331,7 +331,7 @@
     return 0;
   case tok::plus:
     if (getLang().ObjC1) {
-      ParseObjCClassMethodDeclaration();
+      ParseObjCClassMethodDefinition();
     } else {
       Diag(Tok, diag::err_expected_external_declaration);
       ConsumeToken();

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

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Aug 22 17:17:26 2007
@@ -261,7 +261,7 @@
   void ParseObjCClassInstanceVariables(DeclTy *interfaceDecl);
   bool ParseObjCProtocolReferences();
   void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl);
-  DeclTy *ParseObjCAtProtocolDeclaration();
+  DeclTy *ParseObjCAtProtocolDeclaration(SourceLocation atLoc);
   DeclTy *ParseObjCAtImplementationDeclaration();
   DeclTy *ParseObjCAtEndDeclaration();
   DeclTy *ParseObjCAtAliasDeclaration();
@@ -273,8 +273,8 @@
   void ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation mLoc);
   void ParseObjCPropertyDecl(SourceLocation atLoc);
   
-  void ParseObjCInstanceMethodDeclaration();
-  void ParseObjCClassMethodDeclaration();
+  void ParseObjCInstanceMethodDefinition();
+  void ParseObjCClassMethodDefinition();
 
   //===--------------------------------------------------------------------===//
   // C99 6.5: Expressions.





More information about the cfe-commits mailing list