DeclObjC.cpp revision 96e79bfae502212f22148a4ae4fae85244373245
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" 16#include "clang/AST/Stmt.h" 17using namespace clang; 18 19//===----------------------------------------------------------------------===// 20// ObjC Decl Allocation/Deallocation Method Implementations 21//===----------------------------------------------------------------------===// 22 23ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, 24 SourceLocation beginLoc, 25 SourceLocation endLoc, 26 Selector SelInfo, QualType T, 27 DeclContext *contextDecl, 28 bool isInstance, 29 bool isVariadic, 30 bool isSynthesized, 31 ImplementationControl impControl) { 32 return new (C) ObjCMethodDecl(beginLoc, endLoc, 33 SelInfo, T, contextDecl, 34 isInstance, 35 isVariadic, isSynthesized, impControl); 36} 37 38ObjCMethodDecl::~ObjCMethodDecl() { 39 delete [] ParamInfo; 40} 41 42void ObjCMethodDecl::Destroy(ASTContext& C) { 43 if (Body) Body->Destroy(C); 44 if (SelfDecl) SelfDecl->Destroy(C); 45 46 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I) 47 if (*I) (*I)->Destroy(C); 48 49 Decl::Destroy(C); 50} 51 52ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C, 53 DeclContext *DC, 54 SourceLocation atLoc, 55 IdentifierInfo *Id, 56 SourceLocation ClassLoc, 57 bool ForwardDecl, bool isInternal){ 58 return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl, 59 isInternal); 60} 61 62ObjCContainerDecl::~ObjCContainerDecl() { 63} 64 65ObjCInterfaceDecl::~ObjCInterfaceDecl() { 66 delete [] Ivars; 67 // FIXME: CategoryList? 68} 69 70void ObjCInterfaceDecl::Destroy(ASTContext& C) { 71 for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I) 72 if (*I) (*I)->Destroy(C); 73 74 // FIXME: Because there is no clear ownership 75 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they 76 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit. 77 Decl::Destroy(C); 78} 79 80 81ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC, 82 SourceLocation L, IdentifierInfo *Id, 83 QualType T, AccessControl ac, Expr *BW) { 84 return new (C) ObjCIvarDecl(DC, L, Id, T, ac, BW); 85} 86 87 88ObjCAtDefsFieldDecl 89*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 90 IdentifierInfo *Id, QualType T, Expr *BW) { 91 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW); 92} 93 94void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) { 95 this->~ObjCAtDefsFieldDecl(); 96 C.Deallocate((void *)this); 97} 98 99ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC, 100 SourceLocation L, 101 IdentifierInfo *Id) { 102 return new (C) ObjCProtocolDecl(DC, L, Id); 103} 104 105ObjCProtocolDecl::~ObjCProtocolDecl() { 106 delete [] PropertyDecl; 107} 108 109 110ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC, 111 SourceLocation L, 112 ObjCInterfaceDecl **Elts, unsigned nElts) { 113 return new (C) ObjCClassDecl(DC, L, Elts, nElts); 114} 115 116ObjCClassDecl::~ObjCClassDecl() { 117 delete [] ForwardDecls; 118} 119 120void ObjCClassDecl::Destroy(ASTContext& C) { 121 122 // FIXME: There is no clear ownership policy now for referenced 123 // ObjCInterfaceDecls. Some of them can be forward declarations that 124 // are never later defined (in which case the ObjCClassDecl owns them) 125 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally 126 // we should have separate objects for forward declarations and definitions, 127 // obviating this problem. Because of this situation, referenced 128 // ObjCInterfaceDecls are destroyed in ~TranslationUnit. 129 130 Decl::Destroy(C); 131} 132 133ObjCForwardProtocolDecl * 134ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC, 135 SourceLocation L, 136 ObjCProtocolDecl **Elts, unsigned NumElts) { 137 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts); 138} 139 140ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() { 141 delete [] ReferencedProtocols; 142} 143 144ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC, 145 SourceLocation L, 146 IdentifierInfo *Id) { 147 return new (C) ObjCCategoryDecl(DC, L, Id); 148} 149 150ObjCCategoryImplDecl * 151ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC, 152 SourceLocation L,IdentifierInfo *Id, 153 ObjCInterfaceDecl *ClassInterface) { 154 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface); 155} 156 157ObjCImplementationDecl * 158ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC, 159 SourceLocation L, 160 ObjCInterfaceDecl *ClassInterface, 161 ObjCInterfaceDecl *SuperDecl) { 162 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl); 163} 164 165ObjCCompatibleAliasDecl * 166ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC, 167 SourceLocation L, 168 IdentifierInfo *Id, 169 ObjCInterfaceDecl* AliasedClass) { 170 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass); 171} 172 173ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, 174 SourceLocation L, 175 IdentifierInfo *Id, 176 QualType T, 177 PropertyControl propControl) { 178 return new (C) ObjCPropertyDecl(DC, L, Id, T); 179} 180 181//===----------------------------------------------------------------------===// 182// Objective-C Decl Implementation 183//===----------------------------------------------------------------------===// 184 185void ObjCMethodDecl::createImplicitParams(ASTContext &Context, 186 const ObjCInterfaceDecl *OID) { 187 QualType selfTy; 188 if (isInstanceMethod()) { 189 // There may be no interface context due to error in declaration 190 // of the interface (which has been reported). Recover gracefully. 191 if (OID) { 192 selfTy = Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl *>(OID)); 193 selfTy = Context.getPointerType(selfTy); 194 } else { 195 selfTy = Context.getObjCIdType(); 196 } 197 } else // we have a factory method. 198 selfTy = Context.getObjCClassType(); 199 200 SelfDecl = ImplicitParamDecl::Create(Context, this, 201 SourceLocation(), 202 &Context.Idents.get("self"), 203 selfTy); 204 205 CmdDecl = ImplicitParamDecl::Create(Context, this, 206 SourceLocation(), 207 &Context.Idents.get("_cmd"), 208 Context.getObjCSelType()); 209} 210 211void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo, 212 unsigned NumParams) { 213 assert(ParamInfo == 0 && "Already has param info!"); 214 215 // Zero params -> null pointer. 216 if (NumParams) { 217 ParamInfo = new ParmVarDecl*[NumParams]; 218 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); 219 NumMethodParams = NumParams; 220 } 221} 222 223/// FindCategoryDeclaration - Finds category declaration in the list of 224/// categories for this class and returns it. Name of the category is passed 225/// in 'CategoryId'. If category not found, return 0; 226/// 227ObjCCategoryDecl * 228 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const { 229 for (ObjCCategoryDecl *Category = getCategoryList(); 230 Category; Category = Category->getNextClassCategory()) 231 if (Category->getIdentifier() == CategoryId) 232 return Category; 233 return 0; 234} 235 236/// ObjCAddInstanceVariablesToClass - Inserts instance variables 237/// into ObjCInterfaceDecl's fields. 238/// 239void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars, 240 unsigned numIvars, 241 SourceLocation RBrac) { 242 NumIvars = numIvars; 243 if (numIvars) { 244 Ivars = new ObjCIvarDecl*[numIvars]; 245 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*)); 246 } 247 setLocEnd(RBrac); 248} 249 250/// lookupFieldDeclForIvar - looks up a field decl' in the laid out 251/// storage which matches this 'ivar'. 252/// 253FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context, 254 const ObjCIvarDecl *ivar) { 255 const RecordDecl *RecordForDecl = Context.addRecordToClass(this); 256 assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class"); 257 DeclarationName Member = ivar->getDeclName(); 258 DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl)) 259 ->lookup(Member); 260 assert((Lookup.first != Lookup.second) && "field decl not found"); 261 FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first); 262 assert(MemberDecl && "field decl not found"); 263 return MemberDecl; 264} 265 266/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance 267/// Variables (Ivars) relative to what declared in @implementation;s class. 268/// Ivars into ObjCImplementationDecl's fields. 269/// 270void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl( 271 ObjCIvarDecl **ivars, unsigned numIvars) { 272 NumIvars = numIvars; 273 if (numIvars) { 274 Ivars = new ObjCIvarDecl*[numIvars]; 275 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*)); 276 } 277} 278 279// Get the local instance method declared in this interface. 280// FIXME: handle overloading, instance & class methods can have the same name. 281ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const { 282 lookup_const_result MethodResult = lookup(Sel); 283 if (MethodResult.first) 284 return const_cast<ObjCMethodDecl*>( 285 dyn_cast<ObjCMethodDecl>(*MethodResult.first)); 286 return 0; 287} 288 289// Get the local class method declared in this interface. 290ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const { 291 lookup_const_result MethodResult = lookup(Sel); 292 if (MethodResult.first) 293 return const_cast<ObjCMethodDecl*>( 294 dyn_cast<ObjCMethodDecl>(*MethodResult.first)); 295 return 0; 296} 297 298unsigned ObjCContainerDecl::getNumInstanceMethods() const { 299 unsigned sum = 0; 300 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I) 301 sum++; 302 return sum; 303} 304unsigned ObjCContainerDecl::getNumClassMethods() const { 305 unsigned sum = 0; 306 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I) 307 sum++; 308 return sum; 309} 310unsigned ObjCContainerDecl::getNumProperties() const { 311 unsigned sum = 0; 312 for (prop_iterator I=prop_begin(), E=prop_end(); I != E; ++I) 313 sum++; 314 return sum; 315} 316 317/// FindPropertyDeclaration - Finds declaration of the property given its name 318/// in 'PropertyId' and returns it. It returns 0, if not found. 319/// FIXME: Convert to DeclContext lookup... 320/// 321ObjCPropertyDecl * 322ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const { 323 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I) { 324 ObjCPropertyDecl *property = *I; 325 if (property->getIdentifier() == PropertyId) 326 return property; 327 } 328 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this); 329 if (PID) { 330 for (ObjCProtocolDecl::protocol_iterator P = PID->protocol_begin(), 331 E = PID->protocol_end(); 332 P != E; ++P) 333 if (ObjCPropertyDecl *property = 334 (*P)->FindPropertyDeclaration(PropertyId)) 335 return property; 336 } 337 338 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) { 339 // Look through categories. 340 for (ObjCCategoryDecl *Category = OID->getCategoryList(); 341 Category; Category = Category->getNextClassCategory()) { 342 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId); 343 if (property) 344 return property; 345 } 346 // Look through protocols. 347 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(), 348 E = OID->protocol_end(); I != E; ++I) { 349 ObjCProtocolDecl *Protocol = *I; 350 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId); 351 if (property) 352 return property; 353 } 354 if (OID->getSuperClass()) 355 return OID->getSuperClass()->FindPropertyDeclaration(PropertyId); 356 } 357 else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) { 358 // Look through protocols. 359 for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(), 360 E = OCD->protocol_end(); I != E; ++I) { 361 ObjCProtocolDecl *Protocol = *I; 362 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId); 363 if (property) 364 return property; 365 } 366 } 367 return 0; 368} 369 370ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable( 371 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) { 372 ObjCInterfaceDecl* ClassDecl = this; 373 while (ClassDecl != NULL) { 374 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end(); 375 I != E; ++I) { 376 if ((*I)->getIdentifier() == ID) { 377 clsDeclared = ClassDecl; 378 return *I; 379 } 380 } 381 ClassDecl = ClassDecl->getSuperClass(); 382 } 383 return NULL; 384} 385 386/// lookupInstanceMethod - This method returns an instance method by looking in 387/// the class, its categories, and its super classes (using a linear search). 388ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) { 389 ObjCInterfaceDecl* ClassDecl = this; 390 ObjCMethodDecl *MethodDecl = 0; 391 392 while (ClassDecl != NULL) { 393 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel))) 394 return MethodDecl; 395 396 // Didn't find one yet - look through protocols. 397 const ObjCList<ObjCProtocolDecl> &Protocols = 398 ClassDecl->getReferencedProtocols(); 399 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 400 E = Protocols.end(); I != E; ++I) 401 if ((MethodDecl = (*I)->getInstanceMethod(Sel))) 402 return MethodDecl; 403 404 // Didn't find one yet - now look through categories. 405 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList(); 406 while (CatDecl) { 407 if ((MethodDecl = CatDecl->getInstanceMethod(Sel))) 408 return MethodDecl; 409 410 // Didn't find one yet - look through protocols. 411 const ObjCList<ObjCProtocolDecl> &Protocols = 412 CatDecl->getReferencedProtocols(); 413 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 414 E = Protocols.end(); I != E; ++I) 415 if ((MethodDecl = (*I)->getInstanceMethod(Sel))) 416 return MethodDecl; 417 CatDecl = CatDecl->getNextClassCategory(); 418 } 419 ClassDecl = ClassDecl->getSuperClass(); 420 } 421 return NULL; 422} 423 424// lookupClassMethod - This method returns a class method by looking in the 425// class, its categories, and its super classes (using a linear search). 426ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) { 427 ObjCInterfaceDecl* ClassDecl = this; 428 ObjCMethodDecl *MethodDecl = 0; 429 430 while (ClassDecl != NULL) { 431 if ((MethodDecl = ClassDecl->getClassMethod(Sel))) 432 return MethodDecl; 433 434 // Didn't find one yet - look through protocols. 435 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(), 436 E = ClassDecl->protocol_end(); I != E; ++I) 437 if ((MethodDecl = (*I)->getClassMethod(Sel))) 438 return MethodDecl; 439 440 // Didn't find one yet - now look through categories. 441 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList(); 442 while (CatDecl) { 443 if ((MethodDecl = CatDecl->getClassMethod(Sel))) 444 return MethodDecl; 445 CatDecl = CatDecl->getNextClassCategory(); 446 } 447 ClassDecl = ClassDecl->getSuperClass(); 448 } 449 return NULL; 450} 451 452/// getInstanceMethod - This method returns an instance method by 453/// looking in the class implementation. Unlike interfaces, we don't 454/// look outside the implementation. 455ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const { 456 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I) 457 if ((*I)->getSelector() == Sel) 458 return *I; 459 return NULL; 460} 461 462/// getClassMethod - This method returns a class method by looking in 463/// the class implementation. Unlike interfaces, we don't look outside 464/// the implementation. 465ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const { 466 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end(); 467 I != E; ++I) 468 if ((*I)->getSelector() == Sel) 469 return *I; 470 return NULL; 471} 472 473/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl 474/// added to the list of those properties @synthesized/@dynamic in this 475/// @implementation block. 476/// 477ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplDecl(IdentifierInfo *Id) const { 478 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) { 479 ObjCPropertyImplDecl *PID = *i; 480 if (PID->getPropertyDecl()->getIdentifier() == Id) 481 return PID; 482 } 483 return 0; 484} 485 486/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of 487/// properties implemented in this @implementation block and returns the 488/// implemented property that uses it. 489/// 490ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const { 491 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) { 492 ObjCPropertyImplDecl *PID = *i; 493 if (PID->getPropertyIvarDecl() && 494 PID->getPropertyIvarDecl()->getIdentifier() == ivarId) 495 return PID; 496 } 497 return 0; 498} 499 500/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of 501/// properties implemented in this category @implementation block and returns 502/// the implemented property that uses it. 503/// 504ObjCPropertyImplDecl *ObjCCategoryImplDecl:: 505FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const { 506 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){ 507 ObjCPropertyImplDecl *PID = *i; 508 if (PID->getPropertyIvarDecl() && 509 PID->getPropertyIvarDecl()->getIdentifier() == ivarId) 510 return PID; 511 } 512 return 0; 513} 514 515/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl 516/// added to the list of those properties @synthesized/@dynamic in this 517/// category @implementation block. 518/// 519ObjCPropertyImplDecl *ObjCCategoryImplDecl:: 520FindPropertyImplDecl(IdentifierInfo *Id) const { 521 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){ 522 ObjCPropertyImplDecl *PID = *i; 523 if (PID->getPropertyDecl()->getIdentifier() == Id) 524 return PID; 525 } 526 return 0; 527} 528 529// lookupInstanceMethod - This method returns an instance method by looking in 530// the class implementation. Unlike interfaces, we don't look outside the 531// implementation. 532ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const { 533 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I) 534 if ((*I)->getSelector() == Sel) 535 return *I; 536 return NULL; 537} 538 539// lookupClassMethod - This method returns an instance method by looking in 540// the class implementation. Unlike interfaces, we don't look outside the 541// implementation. 542ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const { 543 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end(); 544 I != E; ++I) 545 if ((*I)->getSelector() == Sel) 546 return *I; 547 return NULL; 548} 549 550// lookupInstanceMethod - Lookup a instance method in the protocol and protocols 551// it inherited. 552ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) { 553 ObjCMethodDecl *MethodDecl = NULL; 554 555 if ((MethodDecl = getInstanceMethod(Sel))) 556 return MethodDecl; 557 558 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I) 559 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel))) 560 return MethodDecl; 561 return NULL; 562} 563 564// lookupInstanceMethod - Lookup a class method in the protocol and protocols 565// it inherited. 566ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) { 567 ObjCMethodDecl *MethodDecl = NULL; 568 569 if ((MethodDecl = getClassMethod(Sel))) 570 return MethodDecl; 571 572 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I) 573 if ((MethodDecl = (*I)->lookupClassMethod(Sel))) 574 return MethodDecl; 575 return NULL; 576} 577 578/// getSynthesizedMethodSize - Compute size of synthesized method name 579/// as done be the rewrite. 580/// 581unsigned ObjCMethodDecl::getSynthesizedMethodSize() const { 582 // syntesized method name is a concatenation of -/+[class-name selector] 583 // Get length of this name. 584 unsigned length = 3; // _I_ or _C_ 585 length += getClassInterface()->getNameAsString().size()+1; // extra for _ 586 if (const ObjCCategoryImplDecl *CID = 587 dyn_cast<ObjCCategoryImplDecl>(getDeclContext())) 588 length += CID->getNameAsString().size()+1; 589 length += getSelector().getAsString().size(); // selector name 590 return length; 591} 592 593ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() { 594 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext())) 595 return ID; 596 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext())) 597 return CD->getClassInterface(); 598 if (ObjCImplementationDecl *IMD = 599 dyn_cast<ObjCImplementationDecl>(getDeclContext())) 600 return IMD->getClassInterface(); 601 if (ObjCCategoryImplDecl *CID = 602 dyn_cast<ObjCCategoryImplDecl>(getDeclContext())) 603 return CID->getClassInterface(); 604 assert(false && "unknown method context"); 605 return 0; 606} 607 608ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C, 609 DeclContext *DC, 610 SourceLocation atLoc, 611 SourceLocation L, 612 ObjCPropertyDecl *property, 613 Kind PK, 614 ObjCIvarDecl *ivar) { 615 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar); 616} 617 618 619