]> granicus.if.org Git - clang/commitdiff
Patch for building method declaration nodes. Also fixed a segfault in cocoa.m due
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 12 Sep 2007 18:23:47 +0000 (18:23 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 12 Sep 2007 18:23:47 +0000 (18:23 +0000)
to use of @property.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41880 91177308-0d34-0410-b5e6-96231b3b80d8

AST/Decl.cpp
Parse/ParseObjc.cpp
Sema/Sema.h
Sema/SemaDecl.cpp
include/clang/AST/Decl.h

index 0e6c218f2d5fef71491c544b4dcde818baf84ae7..e84532923be6c157574e8aaf3fb949ffd13e6ee3 100644 (file)
@@ -164,6 +164,22 @@ FieldDecl* RecordDecl::getMember(IdentifierInfo *name) {
   return 0;
 }
 
+void ObjcMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo, 
+                      unsigned NumParams) {
+  assert(ParamInfo == 0 && "Already has param info!");
+
+  // Zero params -> null pointer.
+  if (NumParams) {
+    ParamInfo = new ParmVarDecl*[NumParams];
+    memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
+    NumMethodParams = NumParams;
+  }
+}
+
+ObjcMethodDecl::~ObjcMethodDecl() {
+  delete[] ParamInfo;
+}
+
 /// addObjcMethods - Insert instance and methods declarations into
 /// ObjcInterfaceDecl's InsMethods and ClsMethods fields.
 ///
index 803fe2f6707cea710ded399067c7f216891c3a28..7ddcaabb04b4010d5497cf9390bc55a149bb8024 100644 (file)
@@ -229,7 +229,7 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl) {
         ConsumeToken();
         continue;
       } else if (ocKind == tok::objc_property) {
-        ParseObjCPropertyDecl(0/*FIXME*/);
+        ParseObjCPropertyDecl(interfaceDecl);
         continue;
       } else {
         Diag(Tok, diag::err_objc_illegal_interface_qual);
index b6fe89a3fa19c27e85b2bd55f60cde3cc4de05be..7a3466f97d32d147fe1a2d453ccc41e0c20a4552 100644 (file)
@@ -360,6 +360,13 @@ public:
 
   virtual void ObjcAddMethodsToClass(DeclTy *ClassDecl, 
                                     DeclTy **allMethods, unsigned allNum);
+  virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc, 
+                   tok::TokenKind MethodType, TypeTy *ReturnType,
+                   ObjcKeywordInfo *Keywords, unsigned NumKeywords, 
+                   AttributeList *AttrList);
+  virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc, 
+                   tok::TokenKind MethodType, TypeTy *ReturnType,
+                   IdentifierInfo *SelectorName, AttributeList *AttrList);
                                       
   virtual void ObjcAddInstanceVariable(DeclTy *ClassDec, DeclTy *Ivar,
                                        tok::ObjCKeywordKind visibility);
index 6bfae197e3c12117cee1f1ffce0115b4427b2642..d367038cddfa93cf9f61268b2f352cdcd333a6fd 100644 (file)
@@ -1197,8 +1197,10 @@ void Sema::ParseRecordBody(SourceLocation RecLoc, DeclTy *RecDecl,
 
 void Sema::ObjcAddMethodsToClass(DeclTy *ClassDecl, 
                                 DeclTy **allMethods, unsigned allNum) { 
-  // FIXME: Add method insertion code here.
-#if 0
+  // 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;
@@ -1215,10 +1217,46 @@ void Sema::ObjcAddMethodsToClass(DeclTy *ClassDecl,
   }
   Interface->ObjcAddMethods(&insMethods[0], insMethods.size(), 
                            &clsMethods[0], clsMethods.size());
-#endif
   return;
 }
 
+Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc, 
+                      tok::TokenKind MethodType, TypeTy *ReturnType,
+                      ObjcKeywordInfo *Keywords, unsigned NumKeywords,
+                      AttributeList *AttrList) {
+  assert(NumKeywords && "Selector must be specified");
+  // FIXME: SelectorName to be changed to comform to objc's abi for method names
+  IdentifierInfo *SelectorName = Keywords[0].SelectorName;
+  llvm::SmallVector<ParmVarDecl*, 16> Params;
+
+  for (unsigned i = 0; i < NumKeywords; i++) {
+    ObjcKeywordInfo *arg = &Keywords[i];
+    // FIXME: arg->AttrList must be stored too!
+    ParmVarDecl* Param = new ParmVarDecl(arg->ColonLoc, arg->ArgumentName, 
+                                        QualType::getFromOpaquePtr(arg->TypeInfo), 
+                                        VarDecl::None, 0);
+    // FIXME: 'InvalidType' does not get set by caller yet.
+    if (arg->InvalidType)
+      Param->setInvalidDecl();
+    Params.push_back(Param);
+  }
+  QualType resultDeclType = QualType::getFromOpaquePtr(ReturnType);
+  ObjcMethodDecl* ObjcMethod =  new ObjcMethodDecl(MethodLoc, 
+                                     SelectorName, resultDeclType, 
+                                     0, -1, AttrList, MethodType == tok::minus);
+  ObjcMethod->setMethodParams(&Params[0], NumKeywords);
+  return ObjcMethod;
+}
+
+Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc,  
+                      tok::TokenKind MethodType, TypeTy *ReturnType,
+                      IdentifierInfo *SelectorName, AttributeList *AttrList) {
+  // FIXME: SelectorName to be changed to comform to objc's abi for method names
+  QualType resultDeclType = QualType::getFromOpaquePtr(ReturnType);
+  return new ObjcMethodDecl(MethodLoc, SelectorName, resultDeclType, 0, -1,
+                           AttrList, MethodType == tok::minus);
+}
+
 Sema::DeclTy *Sema::ParseEnumConstant(Scope *S, DeclTy *theEnumDecl,
                                       DeclTy *lastEnumConst,
                                       SourceLocation IdLoc, IdentifierInfo *Id,
index d65ba6e4f45811b6556b423efa33df78b287bef1..aba9e17ded25a5c8bd2c2bad26fd42ecc6b031b7 100644 (file)
@@ -583,19 +583,21 @@ public:
 class ObjcMethodDecl : public Decl {
 public:
   ObjcMethodDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
+                ParmVarDecl **paramInfo = 0, int numParams=-1,
                 AttributeList *M = 0, bool isInstance = true, 
                 Decl *PrevDecl = 0)
-    : Decl(ObjcMethod, L, Id, PrevDecl), MethodDeclType(T), ParamInfo(0), 
+    : Decl(ObjcMethod, L, Id, PrevDecl), MethodDeclType(T), 
+      ParamInfo(paramInfo), NumMethodParams(numParams),
       MethodAttrs(M), IsInstance(isInstance) {}
 
   virtual ~ObjcMethodDecl();
   QualType getMethodType() const { return MethodDeclType; }
-  unsigned getNumMethodParams() const;
+  unsigned getNumMethodParams() const { return NumMethodParams; }
   ParmVarDecl *getMethodParamDecl(unsigned i) {
     assert(i < getNumMethodParams() && "Illegal param #");
     return ParamInfo[i];
   }
-  void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
+  void setMethodParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
 
   AttributeList *getMethodAttrs() const {return MethodAttrs;}
   bool isInstance() const { return IsInstance; }
@@ -610,6 +612,7 @@ 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;
+  int NumMethodParams;  // -1 if no parameters
   
   /// List of attributes for this method declaration.
   AttributeList *MethodAttrs;