diff options
author | Chris Lattner <sabre@nondot.org> | 2008-03-16 00:19:01 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-03-16 00:19:01 +0000 |
commit | 1e03a561f4bd96910cb31a8af53a6ad321a12b51 (patch) | |
tree | 9d8c5b015efdb44fe7464317ecf928fb40d7cffd /lib/AST/DeclObjC.cpp | |
parent | 8e25d8681822d8094bfeb97b2239363552548171 (diff) |
Split objc decl implementation out into DeclObjC.cpp
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48404 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/DeclObjC.cpp')
-rw-r--r-- | lib/AST/DeclObjC.cpp | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp new file mode 100644 index 0000000000..f7f3ada907 --- /dev/null +++ b/lib/AST/DeclObjC.cpp @@ -0,0 +1,312 @@ +//===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the Objective-C related Decl classes. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/DeclObjC.h" +#include "clang/AST/ASTContext.h" +using namespace clang; + + +//===----------------------------------------------------------------------===// +// Objective-C Decl Implementation +//===----------------------------------------------------------------------===// + +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; +} + +/// ObjCAddInstanceVariablesToClass - Inserts instance variables +/// into ObjCInterfaceDecl's fields. +/// +void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars, + unsigned numIvars, + SourceLocation RBrac) { + NumIvars = numIvars; + if (numIvars) { + Ivars = new ObjCIvarDecl*[numIvars]; + memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*)); + } + setLocEnd(RBrac); +} + +/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance +/// Variables (Ivars) relative to what declared in @implementation;s class. +/// Ivars into ObjCImplementationDecl's fields. +/// +void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl( + ObjCIvarDecl **ivars, unsigned numIvars) { + NumIvars = numIvars; + if (numIvars) { + Ivars = new ObjCIvarDecl*[numIvars]; + memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*)); + } +} + +/// addMethods - Insert instance and methods declarations into +/// ObjCInterfaceDecl's InsMethods and ClsMethods fields. +/// +void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods, + unsigned numInsMembers, + ObjCMethodDecl **clsMethods, + unsigned numClsMembers, + SourceLocation endLoc) { + NumInstanceMethods = numInsMembers; + if (numInsMembers) { + InstanceMethods = new ObjCMethodDecl*[numInsMembers]; + memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*)); + } + NumClassMethods = numClsMembers; + if (numClsMembers) { + ClassMethods = new ObjCMethodDecl*[numClsMembers]; + memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*)); + } + AtEndLoc = endLoc; +} + +/// addMethods - Insert instance and methods declarations into +/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields. +/// +void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods, + unsigned numInsMembers, + ObjCMethodDecl **clsMethods, + unsigned numClsMembers, + SourceLocation endLoc) { + NumInstanceMethods = numInsMembers; + if (numInsMembers) { + InstanceMethods = new ObjCMethodDecl*[numInsMembers]; + memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*)); + } + NumClassMethods = numClsMembers; + if (numClsMembers) { + ClassMethods = new ObjCMethodDecl*[numClsMembers]; + memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*)); + } + AtEndLoc = endLoc; +} + +/// addMethods - Insert instance and methods declarations into +/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields. +/// +void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods, + unsigned numInsMembers, + ObjCMethodDecl **clsMethods, + unsigned numClsMembers, + SourceLocation endLoc) { + NumInstanceMethods = numInsMembers; + if (numInsMembers) { + InstanceMethods = new ObjCMethodDecl*[numInsMembers]; + memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*)); + } + NumClassMethods = numClsMembers; + if (numClsMembers) { + ClassMethods = new ObjCMethodDecl*[numClsMembers]; + memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*)); + } + AtEndLoc = endLoc; +} + +ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable( + IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) { + ObjCInterfaceDecl* ClassDecl = this; + while (ClassDecl != NULL) { + for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end(); + I != E; ++I) { + if ((*I)->getIdentifier() == ID) { + clsDeclared = ClassDecl; + return *I; + } + } + ClassDecl = ClassDecl->getSuperClass(); + } + return NULL; +} + +/// lookupInstanceMethod - This method returns an instance method by looking in +/// the class, its categories, and its super classes (using a linear search). +ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) { + ObjCInterfaceDecl* ClassDecl = this; + ObjCMethodDecl *MethodDecl = 0; + + while (ClassDecl != NULL) { + if ((MethodDecl = ClassDecl->getInstanceMethod(Sel))) + return MethodDecl; + + // Didn't find one yet - look through protocols. + ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols(); + int numProtocols = ClassDecl->getNumIntfRefProtocols(); + for (int pIdx = 0; pIdx < numProtocols; pIdx++) { + if ((MethodDecl = protocols[pIdx]->getInstanceMethod(Sel))) + return MethodDecl; + } + // Didn't find one yet - now look through categories. + ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList(); + while (CatDecl) { + if ((MethodDecl = CatDecl->getInstanceMethod(Sel))) + return MethodDecl; + CatDecl = CatDecl->getNextClassCategory(); + } + ClassDecl = ClassDecl->getSuperClass(); + } + return NULL; +} + +// lookupClassMethod - This method returns a class method by looking in the +// class, its categories, and its super classes (using a linear search). +ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) { + ObjCInterfaceDecl* ClassDecl = this; + ObjCMethodDecl *MethodDecl = 0; + + while (ClassDecl != NULL) { + if ((MethodDecl = ClassDecl->getClassMethod(Sel))) + return MethodDecl; + + // Didn't find one yet - look through protocols. + ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols(); + int numProtocols = ClassDecl->getNumIntfRefProtocols(); + for (int pIdx = 0; pIdx < numProtocols; pIdx++) { + if ((MethodDecl = protocols[pIdx]->getClassMethod(Sel))) + return MethodDecl; + } + // Didn't find one yet - now look through categories. + ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList(); + while (CatDecl) { + if ((MethodDecl = CatDecl->getClassMethod(Sel))) + return MethodDecl; + CatDecl = CatDecl->getNextClassCategory(); + } + ClassDecl = ClassDecl->getSuperClass(); + } + return NULL; +} + +/// lookupInstanceMethod - This method returns an instance method by looking in +/// the class implementation. Unlike interfaces, we don't look outside the +/// implementation. +ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) { + for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I) + if ((*I)->getSelector() == Sel) + return *I; + return NULL; +} + +/// lookupClassMethod - This method returns a class method by looking in +/// the class implementation. Unlike interfaces, we don't look outside the +/// implementation. +ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) { + for (classmeth_iterator I = classmeth_begin(), E = classmeth_end(); + I != E; ++I) + if ((*I)->getSelector() == Sel) + return *I; + return NULL; +} + +// lookupInstanceMethod - This method returns an instance method by looking in +// the class implementation. Unlike interfaces, we don't look outside the +// implementation. +ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) { + for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I) + if ((*I)->getSelector() == Sel) + return *I; + return NULL; +} + +// lookupClassMethod - This method returns an instance method by looking in +// the class implementation. Unlike interfaces, we don't look outside the +// implementation. +ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) { + for (classmeth_iterator I = classmeth_begin(), E = classmeth_end(); + I != E; ++I) + if ((*I)->getSelector() == Sel) + return *I; + return NULL; +} + +// lookupInstanceMethod - Lookup a instance method in the protocol and protocols +// it inherited. +ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) { + ObjCMethodDecl *MethodDecl = NULL; + + if ((MethodDecl = getInstanceMethod(Sel))) + return MethodDecl; + + if (getNumReferencedProtocols() > 0) { + ObjCProtocolDecl **RefPDecl = getReferencedProtocols(); + + for (unsigned i = 0; i < getNumReferencedProtocols(); i++) { + if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel))) + return MethodDecl; + } + } + return NULL; +} + +// lookupInstanceMethod - Lookup a class method in the protocol and protocols +// it inherited. +ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) { + ObjCMethodDecl *MethodDecl = NULL; + + if ((MethodDecl = getClassMethod(Sel))) + return MethodDecl; + + if (getNumReferencedProtocols() > 0) { + ObjCProtocolDecl **RefPDecl = getReferencedProtocols(); + + for(unsigned i = 0; i < getNumReferencedProtocols(); i++) { + if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel))) + return MethodDecl; + } + } + return NULL; +} + +/// getSynthesizedMethodSize - Compute size of synthesized method name +/// as done be the rewrite. +/// +unsigned ObjCMethodDecl::getSynthesizedMethodSize() const { + // syntesized method name is a concatenation of -/+[class-name selector] + // Get length of this name. + unsigned length = 3; // _I_ or _C_ + length += strlen(getClassInterface()->getName()) +1; // extra for _ + NamedDecl *MethodContext = getMethodContext(); + if (ObjCCategoryImplDecl *CID = + dyn_cast<ObjCCategoryImplDecl>(MethodContext)) + length += strlen(CID->getName()) +1; + length += getSelector().getName().size(); // selector name + return length; +} + +ObjCInterfaceDecl *const ObjCMethodDecl::getClassInterface() const { + if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext)) + return ID; + if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext)) + return CD->getClassInterface(); + if (ObjCImplementationDecl *IMD = + dyn_cast<ObjCImplementationDecl>(MethodContext)) + return IMD->getClassInterface(); + if (ObjCCategoryImplDecl *CID = + dyn_cast<ObjCCategoryImplDecl>(MethodContext)) + return CID->getClassInterface(); + assert(false && "unknown method context"); + return 0; +} |