DeclObjC.cpp revision 6c4ae5de0c356777446f823b573821fb95560d91
1//===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the Objective-C related Decl classes. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/AST/DeclObjC.h" 15#include "clang/AST/ASTContext.h" 16using namespace clang; 17 18//===----------------------------------------------------------------------===// 19// ObjC Decl Allocation/Deallocation Method Implementations 20//===----------------------------------------------------------------------===// 21 22ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, SourceLocation beginLoc, 23 SourceLocation endLoc, 24 Selector SelInfo, QualType T, 25 Decl *contextDecl, 26 ParmVarDecl **paramInfo, int numParams, 27 AttributeList *M, bool isInstance, 28 bool isVariadic, 29 ImplementationControl impControl, 30 Decl *PrevDecl) { 31 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>(); 32 return new (Mem) ObjCMethodDecl(beginLoc, endLoc, SelInfo, T, contextDecl, 33 paramInfo, numParams, M, isInstance, 34 isVariadic, impControl, PrevDecl); 35 36} 37 38 39//===----------------------------------------------------------------------===// 40// Objective-C Decl Implementation 41//===----------------------------------------------------------------------===// 42 43void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo, 44 unsigned NumParams) { 45 assert(ParamInfo == 0 && "Already has param info!"); 46 47 // Zero params -> null pointer. 48 if (NumParams) { 49 ParamInfo = new ParmVarDecl*[NumParams]; 50 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); 51 NumMethodParams = NumParams; 52 } 53} 54 55ObjCMethodDecl::~ObjCMethodDecl() { 56 delete[] ParamInfo; 57} 58 59/// ObjCAddInstanceVariablesToClass - Inserts instance variables 60/// into ObjCInterfaceDecl's fields. 61/// 62void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars, 63 unsigned numIvars, 64 SourceLocation RBrac) { 65 NumIvars = numIvars; 66 if (numIvars) { 67 Ivars = new ObjCIvarDecl*[numIvars]; 68 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*)); 69 } 70 setLocEnd(RBrac); 71} 72 73/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance 74/// Variables (Ivars) relative to what declared in @implementation;s class. 75/// Ivars into ObjCImplementationDecl's fields. 76/// 77void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl( 78 ObjCIvarDecl **ivars, unsigned numIvars) { 79 NumIvars = numIvars; 80 if (numIvars) { 81 Ivars = new ObjCIvarDecl*[numIvars]; 82 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*)); 83 } 84} 85 86/// addMethods - Insert instance and methods declarations into 87/// ObjCInterfaceDecl's InsMethods and ClsMethods fields. 88/// 89void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods, 90 unsigned numInsMembers, 91 ObjCMethodDecl **clsMethods, 92 unsigned numClsMembers, 93 SourceLocation endLoc) { 94 NumInstanceMethods = numInsMembers; 95 if (numInsMembers) { 96 InstanceMethods = new ObjCMethodDecl*[numInsMembers]; 97 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*)); 98 } 99 NumClassMethods = numClsMembers; 100 if (numClsMembers) { 101 ClassMethods = new ObjCMethodDecl*[numClsMembers]; 102 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*)); 103 } 104 AtEndLoc = endLoc; 105} 106 107/// addMethods - Insert instance and methods declarations into 108/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields. 109/// 110void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods, 111 unsigned numInsMembers, 112 ObjCMethodDecl **clsMethods, 113 unsigned numClsMembers, 114 SourceLocation endLoc) { 115 NumInstanceMethods = numInsMembers; 116 if (numInsMembers) { 117 InstanceMethods = new ObjCMethodDecl*[numInsMembers]; 118 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*)); 119 } 120 NumClassMethods = numClsMembers; 121 if (numClsMembers) { 122 ClassMethods = new ObjCMethodDecl*[numClsMembers]; 123 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*)); 124 } 125 AtEndLoc = endLoc; 126} 127 128/// addMethods - Insert instance and methods declarations into 129/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields. 130/// 131void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods, 132 unsigned numInsMembers, 133 ObjCMethodDecl **clsMethods, 134 unsigned numClsMembers, 135 SourceLocation endLoc) { 136 NumInstanceMethods = numInsMembers; 137 if (numInsMembers) { 138 InstanceMethods = new ObjCMethodDecl*[numInsMembers]; 139 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*)); 140 } 141 NumClassMethods = numClsMembers; 142 if (numClsMembers) { 143 ClassMethods = new ObjCMethodDecl*[numClsMembers]; 144 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*)); 145 } 146 AtEndLoc = endLoc; 147} 148 149ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable( 150 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) { 151 ObjCInterfaceDecl* ClassDecl = this; 152 while (ClassDecl != NULL) { 153 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end(); 154 I != E; ++I) { 155 if ((*I)->getIdentifier() == ID) { 156 clsDeclared = ClassDecl; 157 return *I; 158 } 159 } 160 ClassDecl = ClassDecl->getSuperClass(); 161 } 162 return NULL; 163} 164 165/// lookupInstanceMethod - This method returns an instance method by looking in 166/// the class, its categories, and its super classes (using a linear search). 167ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) { 168 ObjCInterfaceDecl* ClassDecl = this; 169 ObjCMethodDecl *MethodDecl = 0; 170 171 while (ClassDecl != NULL) { 172 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel))) 173 return MethodDecl; 174 175 // Didn't find one yet - look through protocols. 176 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols(); 177 int numProtocols = ClassDecl->getNumIntfRefProtocols(); 178 for (int pIdx = 0; pIdx < numProtocols; pIdx++) { 179 if ((MethodDecl = protocols[pIdx]->getInstanceMethod(Sel))) 180 return MethodDecl; 181 } 182 // Didn't find one yet - now look through categories. 183 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList(); 184 while (CatDecl) { 185 if ((MethodDecl = CatDecl->getInstanceMethod(Sel))) 186 return MethodDecl; 187 CatDecl = CatDecl->getNextClassCategory(); 188 } 189 ClassDecl = ClassDecl->getSuperClass(); 190 } 191 return NULL; 192} 193 194// lookupClassMethod - This method returns a class method by looking in the 195// class, its categories, and its super classes (using a linear search). 196ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) { 197 ObjCInterfaceDecl* ClassDecl = this; 198 ObjCMethodDecl *MethodDecl = 0; 199 200 while (ClassDecl != NULL) { 201 if ((MethodDecl = ClassDecl->getClassMethod(Sel))) 202 return MethodDecl; 203 204 // Didn't find one yet - look through protocols. 205 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols(); 206 int numProtocols = ClassDecl->getNumIntfRefProtocols(); 207 for (int pIdx = 0; pIdx < numProtocols; pIdx++) { 208 if ((MethodDecl = protocols[pIdx]->getClassMethod(Sel))) 209 return MethodDecl; 210 } 211 // Didn't find one yet - now look through categories. 212 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList(); 213 while (CatDecl) { 214 if ((MethodDecl = CatDecl->getClassMethod(Sel))) 215 return MethodDecl; 216 CatDecl = CatDecl->getNextClassCategory(); 217 } 218 ClassDecl = ClassDecl->getSuperClass(); 219 } 220 return NULL; 221} 222 223/// lookupInstanceMethod - This method returns an instance method by looking in 224/// the class implementation. Unlike interfaces, we don't look outside the 225/// implementation. 226ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) { 227 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I) 228 if ((*I)->getSelector() == Sel) 229 return *I; 230 return NULL; 231} 232 233/// lookupClassMethod - This method returns a class method by looking in 234/// the class implementation. Unlike interfaces, we don't look outside the 235/// implementation. 236ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) { 237 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end(); 238 I != E; ++I) 239 if ((*I)->getSelector() == Sel) 240 return *I; 241 return NULL; 242} 243 244// lookupInstanceMethod - This method returns an instance method by looking in 245// the class implementation. Unlike interfaces, we don't look outside the 246// implementation. 247ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) { 248 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I) 249 if ((*I)->getSelector() == Sel) 250 return *I; 251 return NULL; 252} 253 254// lookupClassMethod - This method returns an instance method by looking in 255// the class implementation. Unlike interfaces, we don't look outside the 256// implementation. 257ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) { 258 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end(); 259 I != E; ++I) 260 if ((*I)->getSelector() == Sel) 261 return *I; 262 return NULL; 263} 264 265// lookupInstanceMethod - Lookup a instance method in the protocol and protocols 266// it inherited. 267ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) { 268 ObjCMethodDecl *MethodDecl = NULL; 269 270 if ((MethodDecl = getInstanceMethod(Sel))) 271 return MethodDecl; 272 273 if (getNumReferencedProtocols() > 0) { 274 ObjCProtocolDecl **RefPDecl = getReferencedProtocols(); 275 276 for (unsigned i = 0; i < getNumReferencedProtocols(); i++) { 277 if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel))) 278 return MethodDecl; 279 } 280 } 281 return NULL; 282} 283 284// lookupInstanceMethod - Lookup a class method in the protocol and protocols 285// it inherited. 286ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) { 287 ObjCMethodDecl *MethodDecl = NULL; 288 289 if ((MethodDecl = getClassMethod(Sel))) 290 return MethodDecl; 291 292 if (getNumReferencedProtocols() > 0) { 293 ObjCProtocolDecl **RefPDecl = getReferencedProtocols(); 294 295 for(unsigned i = 0; i < getNumReferencedProtocols(); i++) { 296 if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel))) 297 return MethodDecl; 298 } 299 } 300 return NULL; 301} 302 303/// getSynthesizedMethodSize - Compute size of synthesized method name 304/// as done be the rewrite. 305/// 306unsigned ObjCMethodDecl::getSynthesizedMethodSize() const { 307 // syntesized method name is a concatenation of -/+[class-name selector] 308 // Get length of this name. 309 unsigned length = 3; // _I_ or _C_ 310 length += strlen(getClassInterface()->getName()) +1; // extra for _ 311 NamedDecl *MethodContext = getMethodContext(); 312 if (ObjCCategoryImplDecl *CID = 313 dyn_cast<ObjCCategoryImplDecl>(MethodContext)) 314 length += strlen(CID->getName()) +1; 315 length += getSelector().getName().size(); // selector name 316 return length; 317} 318 319ObjCInterfaceDecl *const ObjCMethodDecl::getClassInterface() const { 320 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext)) 321 return ID; 322 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext)) 323 return CD->getClassInterface(); 324 if (ObjCImplementationDecl *IMD = 325 dyn_cast<ObjCImplementationDecl>(MethodContext)) 326 return IMD->getClassInterface(); 327 if (ObjCCategoryImplDecl *CID = 328 dyn_cast<ObjCCategoryImplDecl>(MethodContext)) 329 return CID->getClassInterface(); 330 assert(false && "unknown method context"); 331 return 0; 332} 333