From: Fariborz Jahanian Date: Wed, 12 Sep 2007 18:23:47 +0000 (+0000) Subject: Patch for building method declaration nodes. Also fixed a segfault in cocoa.m due X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e55cd00d23f0951c29b3b93e6034b2c4b3933a23;p=clang Patch for building method declaration nodes. Also fixed a segfault in cocoa.m due to use of @property. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41880 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/Decl.cpp b/AST/Decl.cpp index 0e6c218f2d..e84532923b 100644 --- a/AST/Decl.cpp +++ b/AST/Decl.cpp @@ -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. /// diff --git a/Parse/ParseObjc.cpp b/Parse/ParseObjc.cpp index 803fe2f670..7ddcaabb04 100644 --- a/Parse/ParseObjc.cpp +++ b/Parse/ParseObjc.cpp @@ -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); diff --git a/Sema/Sema.h b/Sema/Sema.h index b6fe89a3fa..7a3466f97d 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -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); diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 6bfae197e3..d367038cdd 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -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( static_cast(ClassDecl)); llvm::SmallVector 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 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, diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index d65ba6e4f4..aba9e17ded 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -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;