[cfe-commits] r42060 - in /cfe/trunk: AST/Decl.cpp Parse/MinimalAction.cpp Parse/ParseObjc.cpp Sema/Sema.h Sema/SemaDecl.cpp include/clang/AST/Decl.h include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Action.h include/clang/Parse/Parser.h test/Sema/protocol-test-1.m

Fariborz Jahanian fjahanian at apple.com
Mon Sep 17 14:07:37 PDT 2007


Author: fjahanian
Date: Mon Sep 17 16:07:36 2007
New Revision: 42060

URL: http://llvm.org/viewvc/llvm-project?rev=42060&view=rev
Log:
Patch to add objective-c's @protocl type declaration.

Added:
    cfe/trunk/test/Sema/protocol-test-1.m
Modified:
    cfe/trunk/AST/Decl.cpp
    cfe/trunk/Parse/MinimalAction.cpp
    cfe/trunk/Parse/ParseObjc.cpp
    cfe/trunk/Sema/Sema.h
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/include/clang/Parse/Parser.h

Modified: cfe/trunk/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Decl.cpp?rev=42060&r1=42059&r2=42060&view=diff

==============================================================================
--- cfe/trunk/AST/Decl.cpp (original)
+++ cfe/trunk/AST/Decl.cpp Mon Sep 17 16:07:36 2007
@@ -289,3 +289,23 @@
   }
 }
 
+/// ObjcAddProtoMethods - Insert instance and methods declarations into
+/// ObjcProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
+///
+void ObjcProtocolDecl::ObjcAddProtoMethods(ObjcMethodDecl **insMethods, 
+					   unsigned numInsMembers,
+					   ObjcMethodDecl **clsMethods,
+					   unsigned numClsMembers) {
+  NumProtoInsMethods = numInsMembers;
+  if (numInsMembers) {
+    ProtoInsMethods = new ObjcProtoMethodDecl*[numInsMembers];
+    memcpy(ProtoInsMethods, insMethods, numInsMembers*sizeof(ObjcMethodDecl*));
+  }
+  NumProtoClsMethods = numClsMembers;
+  if (numClsMembers) {
+    ProtoClsMethods = new ObjcProtoMethodDecl*[numClsMembers];
+    memcpy(ProtoClsMethods, clsMethods, numClsMembers*sizeof(ObjcMethodDecl*));
+  }
+}
+
+

Modified: cfe/trunk/Parse/MinimalAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/MinimalAction.cpp?rev=42060&r1=42059&r2=42060&view=diff

==============================================================================
--- cfe/trunk/Parse/MinimalAction.cpp (original)
+++ cfe/trunk/Parse/MinimalAction.cpp Mon Sep 17 16:07:36 2007
@@ -80,6 +80,18 @@
   return 0;
 }
 
+Action::DeclTy *
+MinimalAction::ObjcStartProtoInterface(SourceLocation AtProtoInterfaceLoc,
+                 IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
+                 IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs) {
+  
+  TypeNameInfo *TI =
+  new TypeNameInfo(1, ProtocolName->getFETokenInfo<TypeNameInfo>());
+  
+  ProtocolName->setFETokenInfo(TI);
+  return 0;
+}
+
 /// ObjcClassDeclaration - 
 /// Scope will always be top level file scope. 
 Action::DeclTy *

Modified: cfe/trunk/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseObjc.cpp?rev=42060&r1=42059&r2=42060&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Mon Sep 17 16:07:36 2007
@@ -154,7 +154,7 @@
     if (attrList) // categories don't support attributes.
       Diag(Tok, diag::err_objc_no_attributes_on_category);
     
-    ParseObjCInterfaceDeclList(0/*FIXME*/);
+    ParseObjCInterfaceDeclList(0, tok::objc_not_keyword/*FIXME*/);
 
     // The @ sign was already consumed by ParseObjCInterfaceDeclList().
     if (Tok.isObjCAtKeyword(tok::objc_end)) {
@@ -190,7 +190,7 @@
   if (Tok.getKind() == tok::l_brace)
     ParseObjCClassInstanceVariables(ClsType);
 
-  ParseObjCInterfaceDeclList(ClsType);
+  ParseObjCInterfaceDeclList(ClsType, tok::objc_interface);
 
   // The @ sign was already consumed by ParseObjCInterfaceDeclList().
   if (Tok.isObjCAtKeyword(tok::objc_end)) {
@@ -213,8 +213,10 @@
 ///     @required
 ///     @optional
 ///
-void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl) {
+void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
+					tok::ObjCKeywordKind contextKey) {
   llvm::SmallVector<DeclTy*, 32>  allMethods;
+  tok::ObjCKeywordKind pi = tok::objc_not_keyword;
   while (1) {
     if (Tok.getKind() == tok::at) {
       SourceLocation AtLoc = ConsumeToken(); // the "@"
@@ -224,10 +226,14 @@
         break;
       } else if (ocKind == tok::objc_required) { // protocols only
         ConsumeToken();
-        continue;
+	pi = ocKind;
+	if (contextKey != tok::objc_protocol)
+	  Diag(AtLoc, diag::err_objc_protocol_required);
       } else if (ocKind == tok::objc_optional) { // protocols only
         ConsumeToken();
-        continue;
+	pi = ocKind;
+	if (contextKey != tok::objc_protocol)
+	  Diag(AtLoc, diag::err_objc_protocol_optional);
       } else if (ocKind == tok::objc_property) {
         ParseObjCPropertyDecl(interfaceDecl);
         continue;
@@ -237,7 +243,8 @@
       }
     }
     if (Tok.getKind() == tok::minus || Tok.getKind() == tok::plus) {
-      allMethods.push_back(ParseObjCMethodPrototype(interfaceDecl));
+      DeclTy *methodPrototype = ParseObjCMethodPrototype(interfaceDecl, pi);
+      allMethods.push_back(methodPrototype);
       // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
       // method definitions.
       ExpectAndConsume(tok::semi, diag::err_expected_semi_after,"method proto");
@@ -360,14 +367,15 @@
 ///   objc-method-attributes:         [OBJC2]
 ///     __attribute__((deprecated))
 ///
-Parser::DeclTy *Parser::ParseObjCMethodPrototype(DeclTy *CDecl) {
+Parser::DeclTy *Parser::ParseObjCMethodPrototype(DeclTy *IDecl,
+                          tok::ObjCKeywordKind& pi) {
   assert((Tok.getKind() == tok::minus || Tok.getKind() == tok::plus) && 
          "expected +/-");
 
   tok::TokenKind methodType = Tok.getKind();  
   SourceLocation methodLoc = ConsumeToken();
   
-  DeclTy *MDecl = ParseObjCMethodDecl(methodType, methodLoc);
+  DeclTy *MDecl = ParseObjCMethodDecl(IDecl, pi, methodType, methodLoc);
   // Since this rule is used for both method declarations and definitions,
   // the caller is (optionally) responsible for consuming the ';'.
   return MDecl;
@@ -476,8 +484,10 @@
 ///   objc-keyword-attributes:         [OBJC2]
 ///     __attribute__((unused))
 ///
-Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType, 
-                                            SourceLocation mLoc) {
+Parser::DeclTy *Parser::ParseObjCMethodDecl(DeclTy *IDecl,
+                          tok::ObjCKeywordKind& pi, 
+			  tok::TokenKind mType, SourceLocation mLoc) {
+
   TypeTy *ReturnType = 0;
   AttributeList *methodAttrs = 0;
   
@@ -542,7 +552,8 @@
     // If attributes exist after the method, parse them.
     if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute) 
       methodAttrs = ParseAttributes();
-    return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, 
+    return Actions.ObjcBuildMethodDeclaration(IDecl, pi, mLoc, mType, 
+                                              ReturnType, 
                                               &KeyInfo[0], KeyInfo.size(), 
 					      methodAttrs);
   } else if (!selIdent) {
@@ -552,8 +563,9 @@
   if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute) 
     methodAttrs = ParseAttributes();
 
-  return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, selIdent, 
-					    methodAttrs);
+  return Actions.ObjcBuildMethodDeclaration(IDecl, pi,
+                                            mLoc, mType, ReturnType, 
+                                            selIdent, methodAttrs);
 }
 
 ///   objc-protocol-refs:
@@ -724,12 +736,17 @@
     return 0; // FIXME
   }
   // Last, and definitely not least, parse a protocol declaration.
+  llvm::SmallVector<IdentifierInfo *, 8> ProtocolRefs;
   if (Tok.getKind() == tok::less) {
-    llvm::SmallVector<IdentifierInfo *, 8> ProtocolRefs;
     if (ParseObjCProtocolReferences(ProtocolRefs))
       return 0;
   }
-  ParseObjCInterfaceDeclList(0/*FIXME*/);
+  
+  DeclTy *ProtoType = Actions.ObjcStartProtoInterface(AtLoc, 
+                                protocolName, nameLoc,
+                                &ProtocolRefs[0],
+                                ProtocolRefs.size());
+  ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol);
 
   // The @ sign was already consumed by ParseObjCInterfaceDeclList().
   if (Tok.isObjCAtKeyword(tok::objc_end)) {
@@ -900,7 +917,9 @@
 void Parser::ParseObjCInstanceMethodDefinition() {
   assert(Tok.getKind() == tok::minus &&
          "ParseObjCInstanceMethodDefinition(): Expected '-'");
-  ParseObjCMethodPrototype(ObjcImpDecl);
+  // FIXME: @optional/@protocol??
+  tok::ObjCKeywordKind pi = tok::objc_not_keyword;
+  ParseObjCMethodPrototype(ObjcImpDecl, pi);
   // parse optional ';'
   if (Tok.getKind() == tok::semi)
     ConsumeToken();
@@ -918,7 +937,9 @@
 void Parser::ParseObjCClassMethodDefinition() {
   assert(Tok.getKind() == tok::plus &&
          "ParseObjCClassMethodDefinition(): Expected '+'");
-  ParseObjCMethodPrototype(ObjcImpDecl);
+  // FIXME: @optional/@protocol??
+  tok::ObjCKeywordKind pi = tok::objc_not_keyword;
+  ParseObjCMethodPrototype(ObjcImpDecl, pi);
   // parse optional ';'
   if (Tok.getKind() == tok::semi)
     ConsumeToken();

Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=42060&r1=42059&r2=42060&view=diff

==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Mon Sep 17 16:07:36 2007
@@ -358,17 +358,25 @@
                     IdentifierInfo **ProtocolNames, unsigned NumProtocols,
                     AttributeList *AttrList);
                     
+  virtual DeclTy *ObjcStartProtoInterface(SourceLocation AtProtoInterfaceLoc,
+                    IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
+                    IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs);
+  
   virtual DeclTy *ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc,
                                        IdentifierInfo **IdentList,
                                        unsigned NumElts);
 
   virtual void ObjcAddMethodsToClass(DeclTy *ClassDecl, 
 				     DeclTy **allMethods, unsigned allNum);
-  virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc, 
+  virtual DeclTy *ObjcBuildMethodDeclaration(DeclTy *InterfaceDecl,
+                    tok::ObjCKeywordKind& pi, 
+		    SourceLocation MethodLoc, 
 	            tok::TokenKind MethodType, TypeTy *ReturnType,
      		    ObjcKeywordDecl *Keywords, unsigned NumKeywords, 
      		    AttributeList *AttrList);
-  virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc, 
+  virtual DeclTy *ObjcBuildMethodDeclaration(DeclTy *InterfaceDecl,
+                    tok::ObjCKeywordKind& pi, 
+		    SourceLocation MethodLoc, 
  	     	    tok::TokenKind MethodType, TypeTy *ReturnType,
      		    IdentifierInfo *SelectorName, AttributeList *AttrList);
                     

Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=42060&r1=42059&r2=42060&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Mon Sep 17 16:07:36 2007
@@ -28,7 +28,8 @@
 Sema::DeclTy *Sema::isTypeName(const IdentifierInfo &II, Scope *S) const {
   Decl *IIDecl = II.getFETokenInfo<Decl>();
   if (dyn_cast_or_null<TypedefDecl>(IIDecl) || 
-      dyn_cast_or_null<ObjcInterfaceDecl>(IIDecl))
+      dyn_cast_or_null<ObjcInterfaceDecl>(IIDecl) ||
+      dyn_cast_or_null<ObjcProtocolDecl>(IIDecl))
     return IIDecl;
   return 0;
 }
@@ -877,6 +878,20 @@
   return IDecl;
 }
 
+Sema::DeclTy *Sema::ObjcStartProtoInterface(SourceLocation AtProtoInterfaceLoc,
+                IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
+                IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs) {
+  assert(ProtocolName && "Missing protocol identifier");
+  ObjcProtocolDecl *PDecl;
+
+  PDecl = new ObjcProtocolDecl(AtProtoInterfaceLoc, ProtocolName);
+
+  // Chain & install the protocol decl into the identifier.
+  PDecl->setNext(ProtocolName->getFETokenInfo<ScopedDecl>());
+  ProtocolName->setFETokenInfo(PDecl);
+  return PDecl;
+}
+
 /// ObjcClassDeclaration - 
 /// Scope will always be top level file scope. 
 Action::DeclTy *
@@ -1214,19 +1229,17 @@
   }
 }
 
-void Sema::ObjcAddMethodsToClass(DeclTy *ClassDecl, 
-				 DeclTy **allMethods, unsigned allNum) { 
+void Sema::ObjcAddMethodsToClass(DeclTy *ClassDecl,
+                                 DeclTy **allMethods, unsigned allNum) {
   // FIXME: Fix this when we can handle methods declared in protocols.
   // See Parser::ParseObjCAtProtocolDeclaration
   if (!ClassDecl)
     return;
-  ObjcInterfaceDecl *Interface = cast<ObjcInterfaceDecl>(
-				   static_cast<Decl*>(ClassDecl));
   llvm::SmallVector<ObjcMethodDecl*, 32> insMethods;
   llvm::SmallVector<ObjcMethodDecl*, 16> clsMethods;
 
   for (unsigned i = 0; i < allNum; i++ ) {
-    ObjcMethodDecl *Method = 
+    ObjcMethodDecl *Method =
       cast_or_null<ObjcMethodDecl>(static_cast<Decl*>(allMethods[i]));
     if (!Method) continue;  // Already issued a diagnostic.
     if (Method->isInstance())
@@ -1234,12 +1247,26 @@
     else
       clsMethods.push_back(Method);
   }
-  Interface->ObjcAddMethods(&insMethods[0], insMethods.size(), 
-			    &clsMethods[0], clsMethods.size());
+  if (isa<ObjcInterfaceDecl>(static_cast<Decl *>(ClassDecl))) {
+    ObjcInterfaceDecl *Interface = cast<ObjcInterfaceDecl>(
+                                          static_cast<Decl*>(ClassDecl));
+    Interface->ObjcAddMethods(&insMethods[0], insMethods.size(),
+                              &clsMethods[0], clsMethods.size());
+  }
+  else if (isa<ObjcProtocolDecl>(static_cast<Decl *>(ClassDecl))) {
+    ObjcProtocolDecl *Protocol = cast<ObjcProtocolDecl>(
+                                        static_cast<Decl*>(ClassDecl));
+    Protocol->ObjcAddProtoMethods(&insMethods[0], insMethods.size(),
+                                  &clsMethods[0], clsMethods.size());
+  }
+  else
+    assert(0 && "Sema::ObjcAddMethodsToClass(): Unknown DeclTy");
   return;
 }
 
-Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc, 
+Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(DeclTy *IDecl,
+		      tok::ObjCKeywordKind& pi,
+		      SourceLocation MethodLoc, 
                       tok::TokenKind MethodType, TypeTy *ReturnType,
                       ObjcKeywordDecl *Keywords, unsigned NumKeywords,
                       AttributeList *AttrList) {
@@ -1277,21 +1304,57 @@
   }
   QualType resultDeclType = QualType::getFromOpaquePtr(ReturnType);
   ObjcMethodDecl* ObjcMethod;
-  ObjcMethod = new ObjcMethodDecl(MethodLoc, SelName, resultDeclType, 
-                                  0, -1, AttrList, MethodType == tok::minus);
-  ObjcMethod->setMethodParams(&Params[0], NumKeywords);
+// FIXME: Added !IDecl for now to handle @implementation
+  if (!IDecl || isa<ObjcInterfaceDecl>(static_cast<Decl *>(IDecl))) {
+    ObjcMethod =  new ObjcMethodDecl(MethodLoc, SelName, resultDeclType,
+                        0, -1, AttrList, MethodType == tok::minus);
+    ObjcMethod->setMethodParams(&Params[0], NumKeywords);
+  }
+  else if (isa<ObjcProtocolDecl>(static_cast<Decl *>(IDecl))) {
+    ObjcMethod =  new ObjcProtoMethodDecl(MethodLoc, SelName, resultDeclType,
+                        0, -1, AttrList, MethodType == tok::minus);
+    ObjcMethod->setMethodParams(&Params[0], NumKeywords);
+    if (pi == tok::objc_optional)
+      dyn_cast<ObjcProtoMethodDecl>(ObjcMethod)->
+                 setDeclImplementation(ObjcProtoMethodDecl::Optional);
+    else
+      dyn_cast<ObjcProtoMethodDecl>(ObjcMethod)->
+                 setDeclImplementation(ObjcProtoMethodDecl::Required);
+  }
+  else
+    assert(0 && "Sema::ObjcBuildMethodDeclaration(): Unknown DeclTy");
   return ObjcMethod;
 }
 
-Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc,  
+Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(DeclTy *IDecl,
+		      tok::ObjCKeywordKind& pi,
+		      SourceLocation MethodLoc,  
                       tok::TokenKind MethodType, TypeTy *ReturnType,
                       IdentifierInfo *SelectorName, AttributeList *AttrList) {
   const char *methodName = SelectorName->getName();
   SelectorInfo &SelName = Context.getSelectorInfo(methodName, 
                                                   methodName+strlen(methodName));
   QualType resultDeclType = QualType::getFromOpaquePtr(ReturnType);
-  return new ObjcMethodDecl(MethodLoc, SelName, resultDeclType, 0, -1,
-			    AttrList, MethodType == tok::minus);
+  ObjcMethodDecl* ObjcMethod;
+// FIXME: Remove after IDecl is always non-null
+  if (!IDecl || isa<ObjcInterfaceDecl>(static_cast<Decl *>(IDecl))) {
+    ObjcMethod = new ObjcMethodDecl(MethodLoc, SelName, resultDeclType, 0, -1,
+                                    AttrList, MethodType == tok::minus);
+  }
+  else if (isa<ObjcProtocolDecl>(static_cast<Decl *>(IDecl))) {
+    ObjcMethod = new ObjcProtoMethodDecl(MethodLoc, SelName, resultDeclType,
+                                         0, -1,
+                                         AttrList, MethodType == tok::minus);
+    if (pi == tok::objc_optional)
+      dyn_cast<ObjcProtoMethodDecl>(ObjcMethod)->
+                 setDeclImplementation(ObjcProtoMethodDecl::Optional);
+    else
+      dyn_cast<ObjcProtoMethodDecl>(ObjcMethod)->
+                 setDeclImplementation(ObjcProtoMethodDecl::Required);
+  }
+  else
+    assert(0 && "Sema::ObjcBuildMethodDeclaration(): Unknown DeclTy");
+  return ObjcMethod;
 }
 
 Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl,

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=42060&r1=42059&r2=42060&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Mon Sep 17 16:07:36 2007
@@ -670,7 +670,7 @@
 /// ObjcProtoMethodDecl - Each instance represents a method declared
 /// in a protocol. 
 ///
-class ObjcProtoMethodDecl : ObjcMethodDecl {
+class ObjcProtoMethodDecl : public ObjcMethodDecl {
 public:
   ObjcProtoMethodDecl(SourceLocation L, SelectorInfo &Id, QualType T,
                       ParmVarDecl **paramInfo = 0, int numParams=-1,
@@ -710,8 +710,8 @@
       ProtoClsMethods(0), NumProtoClsMethods(-1),
       isForwardProtoDecl(FD) { }
 
-  void ObjcAddProtoMethods(ObjcProtoMethodDecl **insMethods, unsigned numInsMembers,
-                      ObjcProtoMethodDecl **clsMethods, unsigned numClsMembers);
+  void ObjcAddProtoMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers,
+                           ObjcMethodDecl **clsMethods, unsigned numClsMembers);
 
   static bool classof(const Decl *D) {
     return D->getKind() == ObjcProtocol;

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

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Mon Sep 17 16:07:36 2007
@@ -402,6 +402,10 @@
      "setter/getter expects '=' followed by name")
 DIAG(err_objc_expected_property_attr, ERROR,
      "unknown property attribute detected")
+DIAG(err_objc_protocol_required, ERROR,
+     "@required may be specified in protocols only")
+DIAG(err_objc_protocol_optional, ERROR,
+     "@optional may be specified in protocols only")
 
 //===----------------------------------------------------------------------===//
 // Semantic Analysis

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

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Mon Sep 17 16:07:36 2007
@@ -448,13 +448,20 @@
 				     DeclTy **allMethods, unsigned allNum) {
     return;
   }
-  virtual DeclTy *ObjcBuildMethodDeclaration(
+  virtual DeclTy *ObjcStartProtoInterface(SourceLocation AtProtoInterfaceLoc,
+                    IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
+                    IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs) {
+    return 0;
+  }
+  virtual DeclTy *ObjcBuildMethodDeclaration(DeclTy *IDecl,
+    tok::ObjCKeywordKind& pi, 
     SourceLocation MethodLoc, tok::TokenKind MethodType, TypeTy *ReturnType,
     ObjcKeywordDecl *Keywords, unsigned NumKeywords, 
     AttributeList *AttrList) {
     return 0;
   }
-  virtual DeclTy *ObjcBuildMethodDeclaration(
+  virtual DeclTy *ObjcBuildMethodDeclaration(DeclTy *IDecl,
+    tok::ObjCKeywordKind& pi, 
     SourceLocation MethodLoc, tok::TokenKind MethodType, TypeTy *ReturnType,
     IdentifierInfo *SelectorName, AttributeList *AttrList) {
     return 0;
@@ -534,6 +541,10 @@
                     IdentifierInfo *SuperName, SourceLocation SuperLoc,
                     IdentifierInfo **ProtocolNames, unsigned NumProtocols,
                     AttributeList *AttrList);
+  virtual DeclTy *ObjcStartProtoInterface(SourceLocation AtProtoInterfaceLoc,
+                    IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
+                    IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs);
+
 };
 
 }  // end namespace clang

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

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Sep 17 16:07:36 2007
@@ -260,7 +260,8 @@
                                           AttributeList *prefixAttrs = 0);
   void ParseObjCClassInstanceVariables(DeclTy *interfaceDecl);
   bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<IdentifierInfo*> &);
-  void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl);
+  void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
+				  tok::ObjCKeywordKind contextKey);
   DeclTy *ParseObjCAtProtocolDeclaration(SourceLocation atLoc);
   
   DeclTy *ObjcImpDecl;
@@ -288,8 +289,11 @@
 
   TypeTy *ParseObjCTypeName();
   void ParseObjCMethodRequirement();
-  DeclTy *ParseObjCMethodPrototype(DeclTy *classOrCat); 
-  DeclTy *ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation mLoc);
+  DeclTy *ParseObjCMethodPrototype(DeclTy *classOrCat,
+				   tok::ObjCKeywordKind& pi);
+  DeclTy *ParseObjCMethodDecl(DeclTy *CDecl, tok::ObjCKeywordKind& pi,
+			      tok::TokenKind mType, 
+			      SourceLocation mLoc);
   void ParseObjCPropertyAttribute(DeclTy *interfaceDecl);
   void ParseObjCPropertyDecl(DeclTy *interfaceDecl);
   

Added: cfe/trunk/test/Sema/protocol-test-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/protocol-test-1.m?rev=42060&view=auto

==============================================================================
--- cfe/trunk/test/Sema/protocol-test-1.m (added)
+++ cfe/trunk/test/Sema/protocol-test-1.m Mon Sep 17 16:07:36 2007
@@ -0,0 +1,18 @@
+ at protocol PROTO1
+ at required 
+- (int) FooBar;
+ at optional
+- (void) MyMethod1;
++ (int) S;
+ at end
+
+ at interface INTF1
+ at required  // expected-error {{@required may be specified in protocols only}}
+- (int) FooBar;
+- (int) FooBar1;
+- (int) FooBar2;
+ at optional  // expected-error {{@optional may be specified in protocols only}}
++ (int) C;
+
+- (int)I;
+ at end





More information about the cfe-commits mailing list