[cfe-commits] r41801 - in /cfe/trunk: AST/Decl.cpp Parse/ParseObjc.cpp Sema/Sema.h Sema/SemaDecl.cpp include/clang/AST/Decl.h include/clang/Parse/Action.h include/clang/Parse/Parser.h

Fariborz Jahanian fjahanian at apple.com
Mon Sep 10 13:33:04 PDT 2007


Author: fjahanian
Date: Mon Sep 10 15:33:04 2007
New Revision: 41801

URL: http://llvm.org/viewvc/llvm-project?rev=41801&view=rev
Log:
Early patch to collect objective-c methods inserts them in
class object.

Modified:
    cfe/trunk/AST/Decl.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/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=41801&r1=41800&r2=41801&view=diff

==============================================================================
--- cfe/trunk/AST/Decl.cpp (original)
+++ cfe/trunk/AST/Decl.cpp Mon Sep 10 15:33:04 2007
@@ -163,3 +163,23 @@
   }
   return 0;
 }
+
+/// addObjcMethods - Insert instance and methods declarations into
+/// ObjcInterfaceDecl's InsMethods and ClsMethods fields.
+///
+void ObjcInterfaceDecl::ObjcAddMethods(ObjcMethodDecl **insMethods, 
+				       unsigned numInsMembers,
+                                       ObjcMethodDecl **clsMethods,
+                                       unsigned numClsMembers) {
+  NumInsMethods = numInsMembers;
+  if (numInsMembers) {
+    InsMethods = new ObjcMethodDecl*[numInsMembers];
+    memcpy(InsMethods, insMethods, numInsMembers*sizeof(ObjcMethodDecl*));
+  }
+  NumClsMethods = numClsMembers;
+  if (numClsMembers) {
+    ClsMethods = new ObjcMethodDecl*[numClsMembers];
+    memcpy(ClsMethods, clsMethods, numClsMembers*sizeof(ObjcMethodDecl*));
+  }
+}
+

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

==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Mon Sep 10 15:33:04 2007
@@ -214,13 +214,14 @@
 ///     @optional
 ///
 void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl) {
+  llvm::SmallVector<DeclTy*, 32>  allMethods;
   while (1) {
     if (Tok.getKind() == tok::at) {
       SourceLocation AtLoc = ConsumeToken(); // the "@"
       tok::ObjCKeywordKind ocKind = Tok.getObjCKeywordID();
       
       if (ocKind == tok::objc_end) { // terminate list
-        return;
+        break;
       } else if (ocKind == tok::objc_required) { // protocols only
         ConsumeToken();
         continue;
@@ -236,7 +237,7 @@
       }
     }
     if (Tok.getKind() == tok::minus || Tok.getKind() == tok::plus) {
-      ParseObjCMethodPrototype(interfaceDecl);
+      allMethods.push_back(ParseObjCMethodPrototype(interfaceDecl));
       // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
       // method definitions.
       ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "method proto");
@@ -245,13 +246,17 @@
     if (Tok.getKind() == tok::semi)
       ConsumeToken();
     else if (Tok.getKind() == tok::eof)
-      return;
+      break;
     else {
       // FIXME: as the name implies, this rule allows function definitions.
       // We could pass a flag or check for functions during semantic analysis.
       ParseDeclarationOrFunctionDefinition();
     }
   }
+  
+  /// Insert collected methods declarations into the @interface object.
+  Actions.ObjcAddMethodsToClass(interfaceDecl, &allMethods[0], allMethods.size());
+  return;
 }
 
 ///   Parse property attribute declarations.
@@ -364,15 +369,6 @@
   SourceLocation methodLoc = ConsumeToken();
   
   DeclTy *MDecl = ParseObjCMethodDecl(methodType, methodLoc);
-
-  AttributeList *methodAttrs = 0;
-  // If attributes exist after the method, parse them.
-  if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
-    methodAttrs = ParseAttributes();
-
-  if (CDecl)
-    Actions.ObjcAddMethod(CDecl, MDecl, methodAttrs);
-  
   // Since this rule is used for both method declarations and definitions,
   // the caller is responsible for consuming the ';'.
   return MDecl;
@@ -484,6 +480,7 @@
 Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation mLoc) {
 
   TypeTy *ReturnType = 0;
+  AttributeList *methodAttrs = 0;
   
   // Parse the return type.
   if (Tok.getKind() == tok::l_paren)
@@ -491,42 +488,42 @@
   IdentifierInfo *selIdent = ParseObjCSelector();
 
   llvm::SmallVector<ObjcKeywordInfo, 12> KeyInfo;
-  int KeySlot = 0;
   
   if (Tok.getKind() == tok::colon) {
     
     while (1) {
-      KeyInfo[KeySlot].SelectorName = selIdent;
+      ObjcKeywordInfo KeyInfoDecl;
+      KeyInfoDecl.SelectorName = selIdent;
       
       // Each iteration parses a single keyword argument.
       if (Tok.getKind() != tok::colon) {
         Diag(Tok, diag::err_expected_colon);
         break;
       }
-      KeyInfo[KeySlot].ColonLoc = ConsumeToken(); // Eat the ':'.
+      KeyInfoDecl.ColonLoc = ConsumeToken(); // Eat the ':'.
       if (Tok.getKind() == tok::l_paren) // Parse the argument type.
-        KeyInfo[KeySlot].TypeInfo = ParseObjCTypeName();
+        KeyInfoDecl.TypeInfo = ParseObjCTypeName();
 
       // If attributes exist before the argument name, parse them.
       if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
-        KeyInfo[KeySlot].AttrList = ParseAttributes();
+        KeyInfoDecl.AttrList = ParseAttributes();
 
       if (Tok.getKind() != tok::identifier) {
         Diag(Tok, diag::err_expected_ident); // missing argument name.
         break;
       }
-      KeyInfo[KeySlot].ArgumentName = Tok.getIdentifierInfo();
+      KeyInfoDecl.ArgumentName = Tok.getIdentifierInfo();
       ConsumeToken(); // Eat the identifier.
       
       // Rather than call out to the actions, try packaging up the info
       // locally, like we do for Declarator.
       // FIXME: add Actions.BuildObjCKeyword()
       
+      KeyInfo.push_back(KeyInfoDecl);
       selIdent = ParseObjCSelector();
       if (!selIdent && Tok.getKind() != tok::colon)
         break;
       // We have a selector or a colon, continue parsing.
-      KeySlot++;
     }
     // Parse the (optional) parameter list.
     while (Tok.getKind() == tok::comma) {
@@ -543,12 +540,21 @@
       ParseDeclarator(ParmDecl);
     }
     // FIXME: Add support for optional parmameter list...
+    // If attributes exist after the method, parse them.
+    if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute) 
+      methodAttrs = ParseAttributes();
     return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, 
-                                              &KeyInfo[0], KeyInfo.size());
+                                              &KeyInfo[0], KeyInfo.size(), 
+					      methodAttrs);
   } else if (!selIdent) {
     Diag(Tok, diag::err_expected_ident); // missing selector name.
   }
-  return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, selIdent);
+  // If attributes exist after the method, parse them.
+  if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute) 
+    methodAttrs = ParseAttributes();
+
+  return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, selIdent, 
+					    methodAttrs);
 }
 
 ///   objc-protocol-refs:

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

==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Mon Sep 10 15:33:04 2007
@@ -156,6 +156,8 @@
                              Declarator &D, ExprTy *BitfieldWidth);
   virtual void ParseRecordBody(SourceLocation RecLoc, DeclTy *TagDecl,
                                DeclTy **Fields, unsigned NumFields);
+  virtual void ObjcAddMethodsToClass(DeclTy *ClassDecl, 
+				     DeclTy **allMethods, unsigned allNum); 
   virtual DeclTy *ParseEnumConstant(Scope *S, DeclTy *EnumDecl,
                                     DeclTy *LastEnumConstant,
                                     SourceLocation IdLoc, IdentifierInfo *Id,

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

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Mon Sep 10 15:33:04 2007
@@ -1140,6 +1140,30 @@
   Record->defineBody(&RecFields[0], RecFields.size());
 }
 
+void Sema::ObjcAddMethodsToClass(DeclTy *ClassDecl, 
+				 DeclTy **allMethods, unsigned allNum) { 
+  // FIXME: Add method insertion code here.
+#if 0
+  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 = 
+      cast_or_null<ObjcMethodDecl>(static_cast<Decl*>(allMethods[i]));
+    if (!Method) continue;  // Already issued a diagnostic.
+    if (Method->isInstance())
+      insMethods.push_back(Method);
+    else
+      clsMethods.push_back(Method);
+  }
+  Interface->ObjcAddMethods(&insMethods[0], insMethods.size(), 
+			    &clsMethods[0], clsMethods.size());
+#endif
+  return;
+}
+
 Sema::DeclTy *Sema::ParseEnumConstant(Scope *S, DeclTy *theEnumDecl,
                                       DeclTy *lastEnumConst,
                                       SourceLocation IdLoc, IdentifierInfo *Id,

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

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Mon Sep 10 15:33:04 2007
@@ -23,6 +23,8 @@
 class Expr;
 class Stmt;
 class FunctionDecl;
+class ObjcMethodDecl;
+class AttributeList;
 
 
 /// Decl - This represents one declaration (or definition), e.g. a variable, 
@@ -34,7 +36,7 @@
     // Concrete sub-classes of ValueDecl
     Function, BlockVariable, FileVariable, ParmVariable, EnumConstant,
     // Concrete sub-classes of TypeDecl
-    Typedef, Struct, Union, Class, Enum, ObjcInterface, ObjcClass,
+    Typedef, Struct, Union, Class, Enum, ObjcInterface, ObjcClass, ObjcMethod,
     // Concrete sub-class of Decl
     Field
   };
@@ -508,13 +510,25 @@
   FieldDecl **Ivars;   // Null if not defined.
   int NumIvars;   // -1 if not defined.
   
+  /// instance methods
+  ObjcMethodDecl **InsMethods;  // Null if not defined
+  int NumInsMethods;  // -1 if not defined
+  
+  /// class methods
+  ObjcMethodDecl **ClsMethods;  // Null if not defined
+  int NumClsMethods;  // -1 if not defined
+  
   bool isForwardDecl; // declared with @class.
 public:
   ObjcInterfaceDecl(SourceLocation L, IdentifierInfo *Id, bool FD = false)
-    : TypeDecl(ObjcInterface, L, Id, 0), Ivars(0), NumIvars(-1), 
+    : TypeDecl(ObjcInterface, L, Id, 0), Ivars(0), NumIvars(-1),
+      InsMethods(0), NumInsMethods(-1), ClsMethods(0), NumClsMethods(-1),
       isForwardDecl(FD) { }
      
   void addInstanceVariable(FieldDecl ivar);
+
+  void ObjcAddMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers,
+                      ObjcMethodDecl **clsMethods, unsigned numClsMembers);
   
   static bool classof(const Decl *D) {
     return D->getKind() == ObjcInterface;
@@ -544,6 +558,43 @@
   static bool classof(const ObjcClassDecl *D) { return true; }
 };
 
-}  // end namespace clang
+/// ObjcMethodDecl - An instance of this class is created to represent an instance
+/// or class method declaration.
+class ObjcMethodDecl : public ValueDecl {
+public:
+  ObjcMethodDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
+		 bool isInstance = true, Decl *PrevDecl = 0)
+    : ValueDecl(ObjcMethod, L, Id, T, PrevDecl), ParamInfo(0), 
+      MethodAttrs(0), IsInstance(isInstance) {}
+
+  virtual ~ObjcMethodDecl();
+  unsigned getNumParams() const;
+  ParmVarDecl *getParamDecl(unsigned i) {
+    assert(i < getNumParams() && "Illegal param #");
+    return ParamInfo[i];
+  }
+  void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
+
+  bool isInstance() const { return IsInstance; }
+  QualType getResultType() const { return getType(); }
+  
+  void setMethodAttrs(AttributeList *attrs) {MethodAttrs = attrs;}
+  AttributeList *getMethodAttrs() const {return MethodAttrs;}
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return D->getKind() == ObjcMethod; }
+  static bool classof(const ObjcMethodDecl *D) { return true; }
 
+private:
+  /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
+  /// parameters of this Method.  This is null if there are no formals.  
+  ParmVarDecl **ParamInfo;
+  
+  /// List of attributes for this method declaration.
+  AttributeList *MethodAttrs;
+
+  bool IsInstance : 1;
+};
+
+}  // end namespace clang
 #endif

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

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Mon Sep 10 15:33:04 2007
@@ -174,6 +174,9 @@
   virtual void ParseRecordBody(SourceLocation RecLoc, DeclTy *TagDecl,
                                DeclTy **Fields, unsigned NumFields) {}
 
+  virtual void ObjcAddMethodsToClass(DeclTy *ClassDecl,
+				     DeclTy **allMethods, unsigned allNum) {}
+
   virtual DeclTy *ParseEnumConstant(Scope *S, DeclTy *EnumDecl,
                                     DeclTy *LastEnumConstant,
                                     SourceLocation IdLoc, IdentifierInfo *Id,
@@ -450,12 +453,13 @@
   }
   virtual DeclTy *ObjcBuildMethodDeclaration(
     SourceLocation MethodLoc, tok::TokenKind MethodType, TypeTy *ReturnType,
-    ObjcKeywordInfo *Keywords, unsigned NumKeywords) {
+    ObjcKeywordInfo *Keywords, unsigned NumKeywords, 
+    AttributeList *AttrList) {
     return 0;
   }
   virtual DeclTy *ObjcBuildMethodDeclaration(
     SourceLocation MethodLoc, tok::TokenKind MethodType, TypeTy *ReturnType,
-    IdentifierInfo *SelectorName) {
+    IdentifierInfo *SelectorName, AttributeList *AttrList) {
     return 0;
   }
   virtual void ObjCStartCategoryInterface() { // FIXME

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

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Sep 10 15:33:04 2007
@@ -288,7 +288,7 @@
 
   TypeTy *ParseObjCTypeName();
   void ParseObjCMethodRequirement();
-  DeclTy *ParseObjCMethodPrototype(DeclTy *classOrCat);
+  DeclTy *ParseObjCMethodPrototype(DeclTy *classOrCat); 
   DeclTy *ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation mLoc);
   void ParseObjCPropertyAttribute(DeclTy *interfaceDecl);
   void ParseObjCPropertyDecl(DeclTy *interfaceDecl);





More information about the cfe-commits mailing list