DeclObjC.h revision 7e7e3872b584bc5e7de7a34c8b9c092032303b72
1//===--- DeclObjC.h - Classes for representing declarations -----*- C++ -*-===// 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 defines the DeclObjC interface and subclasses. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_AST_DECLOBJC_H 15#define LLVM_CLANG_AST_DECLOBJC_H 16 17#include "clang/AST/Decl.h" 18#include "clang/Basic/IdentifierTable.h" 19 20namespace clang { 21class Expr; 22class Stmt; 23class FunctionDecl; 24class AttributeList; 25class ObjCIvarDecl; 26class ObjCMethodDecl; 27class ObjCProtocolDecl; 28class ObjCCategoryDecl; 29class ObjCPropertyDecl; 30 31/// ObjCMethodDecl - Represents an instance or class method declaration. 32/// ObjC methods can be declared within 4 contexts: class interfaces, 33/// categories, protocols, and class implementations. While C++ member 34/// functions leverage C syntax, Objective-C method syntax is modeled after 35/// Smalltalk (using colons to specify argument types/expressions). 36/// Here are some brief examples: 37/// 38/// Setter/getter instance methods: 39/// - (void)setMenu:(NSMenu *)menu; 40/// - (NSMenu *)menu; 41/// 42/// Instance method that takes 2 NSView arguments: 43/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView; 44/// 45/// Getter class method: 46/// + (NSMenu *)defaultMenu; 47/// 48/// A selector represents a unique name for a method. The selector names for 49/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu. 50/// 51class ObjCMethodDecl : public Decl, public DeclContext { 52public: 53 enum ImplementationControl { None, Required, Optional }; 54private: 55 /// Bitfields must be first fields in this class so they pack with those 56 /// declared in class Decl. 57 /// instance (true) or class (false) method. 58 bool IsInstance : 1; 59 bool IsVariadic : 1; 60 61 // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum 62 /// @required/@optional 63 unsigned DeclImplementation : 2; 64 65 // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum 66 /// in, inout, etc. 67 unsigned objcDeclQualifier : 6; 68 69 // Context this method is declared in. 70 NamedDecl *MethodContext; 71 72 // A unigue name for this method. 73 Selector SelName; 74 75 // Type of this method. 76 QualType MethodDeclType; 77 /// ParamInfo - new[]'d array of pointers to VarDecls for the formal 78 /// parameters of this Method. This is null if there are no formals. 79 ParmVarDecl **ParamInfo; 80 unsigned NumMethodParams; 81 82 /// List of attributes for this method declaration. 83 AttributeList *MethodAttrs; 84 85 SourceLocation EndLoc; // the location of the ';' or '{'. 86 87 // The following are only used for method definitions, null otherwise. 88 // FIXME: space savings opportunity, consider a sub-class. 89 Stmt *Body; 90 ParmVarDecl *SelfDecl; 91 92 ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc, 93 Selector SelInfo, QualType T, 94 Decl *contextDecl, 95 AttributeList *M = 0, bool isInstance = true, 96 bool isVariadic = false, 97 ImplementationControl impControl = None) 98 : Decl(ObjCMethod, beginLoc), 99 DeclContext(ObjCMethod), 100 IsInstance(isInstance), IsVariadic(isVariadic), 101 DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None), 102 MethodContext(static_cast<NamedDecl*>(contextDecl)), 103 SelName(SelInfo), MethodDeclType(T), 104 ParamInfo(0), NumMethodParams(0), 105 MethodAttrs(M), EndLoc(endLoc), Body(0), SelfDecl(0) {} 106 ~ObjCMethodDecl(); 107public: 108 109 static ObjCMethodDecl *Create(ASTContext &C, 110 SourceLocation beginLoc, 111 SourceLocation endLoc, Selector SelInfo, 112 QualType T, Decl *contextDecl, 113 AttributeList *M = 0, bool isInstance = true, 114 bool isVariadic = false, 115 ImplementationControl impControl = None); 116 117 ObjCDeclQualifier getObjCDeclQualifier() const { 118 return ObjCDeclQualifier(objcDeclQualifier); 119 } 120 void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; } 121 122 // Location information, modeled after the Stmt API. 123 SourceLocation getLocStart() const { return getLocation(); } 124 SourceLocation getLocEnd() const { return EndLoc; } 125 126 NamedDecl *getMethodContext() const { return MethodContext; } 127 128 ObjCInterfaceDecl *getClassInterface(); 129 const ObjCInterfaceDecl *getClassInterface() const { 130 return const_cast<ObjCMethodDecl*>(this)->getClassInterface(); 131 } 132 133 Selector getSelector() const { return SelName; } 134 unsigned getSynthesizedMethodSize() const; 135 QualType getResultType() const { return MethodDeclType; } 136 137 // Iterator access to formal parameters. 138 unsigned param_size() const { return NumMethodParams; } 139 typedef ParmVarDecl **param_iterator; 140 typedef ParmVarDecl * const *param_const_iterator; 141 param_iterator param_begin() { return ParamInfo; } 142 param_iterator param_end() { return ParamInfo+param_size(); } 143 param_const_iterator param_begin() const { return ParamInfo; } 144 param_const_iterator param_end() const { return ParamInfo+param_size(); } 145 146 unsigned getNumParams() const { return NumMethodParams; } 147 ParmVarDecl *getParamDecl(unsigned i) const { 148 assert(i < getNumParams() && "Illegal param #"); 149 return ParamInfo[i]; 150 } 151 void setParamDecl(int i, ParmVarDecl *pDecl) { 152 ParamInfo[i] = pDecl; 153 } 154 void setMethodParams(ParmVarDecl **NewParamInfo, unsigned NumParams); 155 156 AttributeList *getMethodAttrs() const {return MethodAttrs;} 157 bool isInstance() const { return IsInstance; } 158 bool isVariadic() const { return IsVariadic; } 159 160 // Related to protocols declared in @protocol 161 void setDeclImplementation(ImplementationControl ic) { 162 DeclImplementation = ic; 163 } 164 ImplementationControl getImplementationControl() const { 165 return ImplementationControl(DeclImplementation); 166 } 167 Stmt *getBody() { return Body; } 168 const Stmt *getBody() const { return Body; } 169 void setBody(Stmt *B) { Body = B; } 170 171 const ParmVarDecl *getSelfDecl() const { return SelfDecl; } 172 ParmVarDecl *getSelfDecl() { return SelfDecl; } 173 void setSelfDecl(ParmVarDecl *PVD) { SelfDecl = PVD; } 174 175 // Implement isa/cast/dyncast/etc. 176 static bool classof(const Decl *D) { return D->getKind() == ObjCMethod; } 177 static bool classof(const ObjCMethodDecl *D) { return true; } 178 179 friend void Decl::Destroy(ASTContext& C) const; 180}; 181 182/// ObjCInterfaceDecl - Represents an ObjC class declaration. For example: 183/// 184/// // MostPrimitive declares no super class (not particularly useful). 185/// @interface MostPrimitive 186/// // no instance variables or methods. 187/// @end 188/// 189/// // NSResponder inherits from NSObject & implements NSCoding (a protocol). 190/// @interface NSResponder : NSObject <NSCoding> 191/// { // instance variables are represented by ObjCIvarDecl. 192/// id nextResponder; // nextResponder instance variable. 193/// } 194/// - (NSResponder *)nextResponder; // return a pointer to NSResponder. 195/// - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer 196/// @end // to an NSEvent. 197/// 198/// Unlike C/C++, forward class declarations are accomplished with @class. 199/// Unlike C/C++, @class allows for a list of classes to be forward declared. 200/// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes 201/// typically inherit from NSObject (an exception is NSProxy). 202/// 203class ObjCInterfaceDecl : public NamedDecl, public DeclContext { 204 /// TypeForDecl - This indicates the Type object that represents this 205 /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType 206 Type *TypeForDecl; 207 friend class ASTContext; 208 209 /// Class's super class. 210 ObjCInterfaceDecl *SuperClass; 211 212 /// Protocols referenced in interface header declaration 213 ObjCProtocolDecl **ReferencedProtocols; // Null if none 214 unsigned NumReferencedProtocols; // 0 if none 215 216 /// Ivars/NumIvars - This is a new[]'d array of pointers to Decls. 217 ObjCIvarDecl **Ivars; // Null if not defined. 218 unsigned NumIvars; // 0 if none. 219 220 /// instance methods 221 ObjCMethodDecl **InstanceMethods; // Null if not defined 222 unsigned NumInstanceMethods; // 0 if none. 223 224 /// class methods 225 ObjCMethodDecl **ClassMethods; // Null if not defined 226 unsigned NumClassMethods; // 0 if none 227 228 /// List of categories defined for this class. 229 ObjCCategoryDecl *CategoryList; 230 231 /// class properties 232 ObjCPropertyDecl **PropertyDecl; // Null if no property 233 unsigned NumPropertyDecl; // 0 if none. 234 235 bool ForwardDecl:1; // declared with @class. 236 bool InternalInterface:1; // true - no @interface for @implementation 237 238 SourceLocation ClassLoc; // location of the class identifier. 239 SourceLocation SuperClassLoc; // location of the super class identifier. 240 SourceLocation EndLoc; // marks the '>', '}', or identifier. 241 SourceLocation AtEndLoc; // marks the end of the entire interface. 242 243 ObjCInterfaceDecl(SourceLocation atLoc, 244 unsigned numRefProtos, 245 IdentifierInfo *Id, SourceLocation CLoc, 246 bool FD, bool isInternal) 247 : NamedDecl(ObjCInterface, atLoc, Id), DeclContext(ObjCInterface), 248 TypeForDecl(0), SuperClass(0), 249 ReferencedProtocols(0), NumReferencedProtocols(0), Ivars(0), 250 NumIvars(0), 251 InstanceMethods(0), NumInstanceMethods(0), 252 ClassMethods(0), NumClassMethods(0), 253 CategoryList(0), PropertyDecl(0), NumPropertyDecl(0), 254 ForwardDecl(FD), InternalInterface(isInternal), 255 ClassLoc(CLoc) { 256 AllocIntfRefProtocols(numRefProtos); 257 } 258public: 259 260 static ObjCInterfaceDecl *Create(ASTContext &C, 261 SourceLocation atLoc, 262 unsigned numRefProtos, 263 IdentifierInfo *Id, 264 SourceLocation ClassLoc = SourceLocation(), 265 bool ForwardDecl = false, 266 bool isInternal = false); 267 268 // This is necessary when converting a forward declaration to a definition. 269 void AllocIntfRefProtocols(unsigned numRefProtos) { 270 if (numRefProtos) { 271 ReferencedProtocols = new ObjCProtocolDecl*[numRefProtos]; 272 memset(ReferencedProtocols, '\0', 273 numRefProtos*sizeof(ObjCProtocolDecl*)); 274 NumReferencedProtocols = numRefProtos; 275 } 276 } 277 278 ObjCProtocolDecl **getReferencedProtocols() const { 279 return ReferencedProtocols; 280 } 281 unsigned getNumIntfRefProtocols() const { return NumReferencedProtocols; } 282 283 typedef ObjCIvarDecl * const *ivar_iterator; 284 ivar_iterator ivar_begin() const { return Ivars; } 285 ivar_iterator ivar_end() const { return Ivars + ivar_size();} 286 unsigned ivar_size() const { return NumIvars; } 287 288 unsigned getNumInstanceMethods() const { return NumInstanceMethods; } 289 unsigned getNumClassMethods() const { return NumClassMethods; } 290 291 typedef ObjCMethodDecl * const * instmeth_iterator; 292 instmeth_iterator instmeth_begin() const { return InstanceMethods; } 293 instmeth_iterator instmeth_end() const { 294 return InstanceMethods+NumInstanceMethods; 295 } 296 297 typedef ObjCMethodDecl * const * classmeth_iterator; 298 classmeth_iterator classmeth_begin() const { return ClassMethods; } 299 classmeth_iterator classmeth_end() const { 300 return ClassMethods+NumClassMethods; 301 } 302 303 void addInstanceVariablesToClass(ObjCIvarDecl **ivars, unsigned numIvars, 304 SourceLocation RBracLoc); 305 306 void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers, 307 ObjCMethodDecl **clsMethods, unsigned numClsMembers, 308 SourceLocation AtEnd); 309 310 void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties); 311 312 313 bool isForwardDecl() const { return ForwardDecl; } 314 void setForwardDecl(bool val) { ForwardDecl = val; } 315 316 void setIntfRefProtocols(unsigned idx, ObjCProtocolDecl *OID) { 317 assert((idx < NumReferencedProtocols) && "index out of range"); 318 ReferencedProtocols[idx] = OID; 319 } 320 321 ObjCInterfaceDecl *getSuperClass() const { return SuperClass; } 322 void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; } 323 324 ObjCCategoryDecl* getCategoryList() const { return CategoryList; } 325 void setCategoryList(ObjCCategoryDecl *category) { 326 CategoryList = category; 327 } 328 329 /// isSuperClassOf - Return true if this class is the specified class or is a 330 /// super class of the specified interface class. 331 bool isSuperClassOf(const ObjCInterfaceDecl *I) const { 332 // If RHS is derived from LHS it is OK; else it is not OK. 333 while (I != NULL) { 334 if (this == I) 335 return true; 336 I = I->getSuperClass(); 337 } 338 return false; 339 } 340 341 ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *ivarName, 342 ObjCInterfaceDecl *&clsDeclared); 343 344 // Get the local instance method declared in this interface. 345 ObjCMethodDecl *getInstanceMethod(Selector Sel) { 346 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); 347 I != E; ++I) { 348 if ((*I)->getSelector() == Sel) 349 return *I; 350 } 351 return 0; 352 } 353 // Get the local class method declared in this interface. 354 ObjCMethodDecl *getClassMethod(Selector Sel) { 355 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end(); 356 I != E; ++I) { 357 if ((*I)->getSelector() == Sel) 358 return *I; 359 } 360 return 0; 361 } 362 // Lookup a method. First, we search locally. If a method isn't 363 // found, we search referenced protocols and class categories. 364 ObjCMethodDecl *lookupInstanceMethod(Selector Sel); 365 ObjCMethodDecl *lookupClassMethod(Selector Sel); 366 367 // Location information, modeled after the Stmt API. 368 SourceLocation getLocStart() const { return getLocation(); } // '@'interface 369 SourceLocation getLocEnd() const { return EndLoc; } 370 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 371 372 SourceLocation getClassLoc() const { return ClassLoc; } 373 void setSuperClassLoc(SourceLocation Loc) { SuperClassLoc = Loc; } 374 SourceLocation getSuperClassLoc() const { return SuperClassLoc; } 375 376 // We also need to record the @end location. 377 SourceLocation getAtEndLoc() const { return AtEndLoc; } 378 379 unsigned getNumPropertyDecl() const { return NumPropertyDecl; } 380 381 ObjCPropertyDecl * const * getPropertyDecl() const { return PropertyDecl; } 382 ObjCPropertyDecl **getPropertyDecl() { return PropertyDecl; } 383 384 /// ImplicitInterfaceDecl - check that this is an implicitely declared 385 /// ObjCInterfaceDecl node. This is for legacy objective-c @implementation 386 /// declaration without an @interface declaration. 387 bool ImplicitInterfaceDecl() const { return InternalInterface; } 388 389 static bool classof(const Decl *D) { return D->getKind() == ObjCInterface; } 390 static bool classof(const ObjCInterfaceDecl *D) { return true; } 391}; 392 393/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC 394/// instance variables are identical to C. The only exception is Objective-C 395/// supports C++ style access control. For example: 396/// 397/// @interface IvarExample : NSObject 398/// { 399/// id defaultToPrivate; // same as C++. 400/// @public: 401/// id canBePublic; // same as C++. 402/// @protected: 403/// id canBeProtected; // same as C++. 404/// @package: 405/// id canBePackage; // framework visibility (not available in C++). 406/// } 407/// 408class ObjCIvarDecl : public FieldDecl { 409 ObjCIvarDecl(SourceLocation L, IdentifierInfo *Id, QualType T) 410 : FieldDecl(ObjCIvar, L, Id, T) {} 411public: 412 static ObjCIvarDecl *Create(ASTContext &C, SourceLocation L, 413 IdentifierInfo *Id, QualType T); 414 415 enum AccessControl { 416 None, Private, Protected, Public, Package 417 }; 418 void setAccessControl(AccessControl ac) { DeclAccess = ac; } 419 AccessControl getAccessControl() const { return AccessControl(DeclAccess); } 420 421 // Implement isa/cast/dyncast/etc. 422 static bool classof(const Decl *D) { return D->getKind() == ObjCIvar; } 423 static bool classof(const ObjCIvarDecl *D) { return true; } 424private: 425 // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum 426 unsigned DeclAccess : 3; 427}; 428 429 430/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols 431/// declare a pure abstract type (i.e no instance variables are permitted). 432/// Protocols orginally drew inspiration from C++ pure virtual functions (a C++ 433/// feature with nice semantics and lousy syntax:-). Here is an example: 434/// 435/// @protocol NSDraggingInfo <refproto1, refproto2> 436/// - (NSWindow *)draggingDestinationWindow; 437/// - (NSImage *)draggedImage; 438/// @end 439/// 440/// This says that NSDraggingInfo requires two methods and requires everything 441/// that the two "referenced protocols" 'refproto1' and 'refproto2' require as 442/// well. 443/// 444/// @interface ImplementsNSDraggingInfo : NSObject <NSDraggingInfo> 445/// @end 446/// 447/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and 448/// protocols are in distinct namespaces. For example, Cocoa defines both 449/// an NSObject protocol and class (which isn't allowed in Java). As a result, 450/// protocols are referenced using angle brackets as follows: 451/// 452/// id <NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo; 453/// 454class ObjCProtocolDecl : public NamedDecl { 455 /// referenced protocols 456 ObjCProtocolDecl **ReferencedProtocols; // Null if none 457 unsigned NumReferencedProtocols; // 0 if none 458 459 /// protocol instance methods 460 ObjCMethodDecl **InstanceMethods; // Null if not defined 461 unsigned NumInstanceMethods; // 0 if none 462 463 /// protocol class methods 464 ObjCMethodDecl **ClassMethods; // Null if not defined 465 unsigned NumClassMethods; // 0 if none 466 467 bool isForwardProtoDecl; // declared with @protocol. 468 469 SourceLocation EndLoc; // marks the '>' or identifier. 470 SourceLocation AtEndLoc; // marks the end of the entire interface. 471 472 ObjCProtocolDecl(SourceLocation L, unsigned numRefProtos, IdentifierInfo *Id) 473 : NamedDecl(ObjCProtocol, L, Id), 474 ReferencedProtocols(0), NumReferencedProtocols(0), 475 InstanceMethods(0), NumInstanceMethods(0), 476 ClassMethods(0), NumClassMethods(0), 477 isForwardProtoDecl(true) { 478 AllocReferencedProtocols(numRefProtos); 479 } 480public: 481 static ObjCProtocolDecl *Create(ASTContext &C, SourceLocation L, 482 unsigned numRefProtos, IdentifierInfo *Id); 483 484 void AllocReferencedProtocols(unsigned numRefProtos) { 485 if (numRefProtos) { 486 ReferencedProtocols = new ObjCProtocolDecl*[numRefProtos]; 487 memset(ReferencedProtocols, '\0', 488 numRefProtos*sizeof(ObjCProtocolDecl*)); 489 NumReferencedProtocols = numRefProtos; 490 } 491 } 492 void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers, 493 ObjCMethodDecl **clsMethods, unsigned numClsMembers, 494 SourceLocation AtEndLoc); 495 496 void setReferencedProtocols(unsigned idx, ObjCProtocolDecl *OID) { 497 assert((idx < NumReferencedProtocols) && "index out of range"); 498 ReferencedProtocols[idx] = OID; 499 } 500 501 ObjCProtocolDecl** getReferencedProtocols() const { 502 return ReferencedProtocols; 503 } 504 unsigned getNumReferencedProtocols() const { return NumReferencedProtocols; } 505 unsigned getNumInstanceMethods() const { return NumInstanceMethods; } 506 unsigned getNumClassMethods() const { return NumClassMethods; } 507 508 typedef ObjCMethodDecl * const * instmeth_iterator; 509 instmeth_iterator instmeth_begin() const { return InstanceMethods; } 510 instmeth_iterator instmeth_end() const { 511 return InstanceMethods+NumInstanceMethods; 512 } 513 514 typedef ObjCMethodDecl * const * classmeth_iterator; 515 classmeth_iterator classmeth_begin() const { return ClassMethods; } 516 classmeth_iterator classmeth_end() const { 517 return ClassMethods+NumClassMethods; 518 } 519 520 // Get the local instance method declared in this interface. 521 ObjCMethodDecl *getInstanceMethod(Selector Sel) { 522 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); 523 I != E; ++I) { 524 if ((*I)->getSelector() == Sel) 525 return *I; 526 } 527 return 0; 528 } 529 // Get the local class method declared in this interface. 530 ObjCMethodDecl *getClassMethod(Selector Sel) { 531 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end(); 532 I != E; ++I) { 533 if ((*I)->getSelector() == Sel) 534 return *I; 535 } 536 return 0; 537 } 538 539 // Lookup a method. First, we search locally. If a method isn't 540 // found, we search referenced protocols and class categories. 541 ObjCMethodDecl *lookupInstanceMethod(Selector Sel); 542 ObjCMethodDecl *lookupClassMethod(Selector Sel); 543 544 bool isForwardDecl() const { return isForwardProtoDecl; } 545 void setForwardDecl(bool val) { isForwardProtoDecl = val; } 546 547 // Location information, modeled after the Stmt API. 548 SourceLocation getLocStart() const { return getLocation(); } // '@'protocol 549 SourceLocation getLocEnd() const { return EndLoc; } 550 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 551 552 // We also need to record the @end location. 553 SourceLocation getAtEndLoc() const { return AtEndLoc; } 554 555 static bool classof(const Decl *D) { return D->getKind() == ObjCProtocol; } 556 static bool classof(const ObjCProtocolDecl *D) { return true; } 557}; 558 559/// ObjCClassDecl - Specifies a list of forward class declarations. For example: 560/// 561/// @class NSCursor, NSImage, NSPasteboard, NSWindow; 562/// 563class ObjCClassDecl : public Decl { 564 ObjCInterfaceDecl **ForwardDecls; 565 unsigned NumForwardDecls; 566 567 ObjCClassDecl(SourceLocation L, ObjCInterfaceDecl **Elts, unsigned nElts) 568 : Decl(ObjCClass, L) { 569 if (nElts) { 570 ForwardDecls = new ObjCInterfaceDecl*[nElts]; 571 memcpy(ForwardDecls, Elts, nElts*sizeof(ObjCInterfaceDecl*)); 572 } else { 573 ForwardDecls = 0; 574 } 575 NumForwardDecls = nElts; 576 } 577public: 578 static ObjCClassDecl *Create(ASTContext &C, SourceLocation L, 579 ObjCInterfaceDecl **Elts, unsigned nElts); 580 581 void setInterfaceDecl(unsigned idx, ObjCInterfaceDecl *OID) { 582 assert(idx < NumForwardDecls && "index out of range"); 583 ForwardDecls[idx] = OID; 584 } 585 ObjCInterfaceDecl** getForwardDecls() const { return ForwardDecls; } 586 int getNumForwardDecls() const { return NumForwardDecls; } 587 588 static bool classof(const Decl *D) { return D->getKind() == ObjCClass; } 589 static bool classof(const ObjCClassDecl *D) { return true; } 590}; 591 592/// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations. 593/// For example: 594/// 595/// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo; 596/// 597class ObjCForwardProtocolDecl : public Decl { 598 ObjCProtocolDecl **ReferencedProtocols; 599 unsigned NumReferencedProtocols; 600 601 ObjCForwardProtocolDecl(SourceLocation L, 602 ObjCProtocolDecl **Elts, unsigned nElts) 603 : Decl(ObjCForwardProtocol, L) { 604 NumReferencedProtocols = nElts; 605 if (nElts) { 606 ReferencedProtocols = new ObjCProtocolDecl*[nElts]; 607 memcpy(ReferencedProtocols, Elts, nElts*sizeof(ObjCProtocolDecl*)); 608 } else { 609 ReferencedProtocols = 0; 610 } 611 } 612public: 613 static ObjCForwardProtocolDecl *Create(ASTContext &C, SourceLocation L, 614 ObjCProtocolDecl **Elts, unsigned Num); 615 616 617 void setForwardProtocolDecl(unsigned idx, ObjCProtocolDecl *OID) { 618 assert(idx < NumReferencedProtocols && "index out of range"); 619 ReferencedProtocols[idx] = OID; 620 } 621 622 unsigned getNumForwardDecls() const { return NumReferencedProtocols; } 623 624 ObjCProtocolDecl *getForwardProtocolDecl(unsigned idx) { 625 assert(idx < NumReferencedProtocols && "index out of range"); 626 return ReferencedProtocols[idx]; 627 } 628 const ObjCProtocolDecl *getForwardProtocolDecl(unsigned idx) const { 629 assert(idx < NumReferencedProtocols && "index out of range"); 630 return ReferencedProtocols[idx]; 631 } 632 633 static bool classof(const Decl *D) { 634 return D->getKind() == ObjCForwardProtocol; 635 } 636 static bool classof(const ObjCForwardProtocolDecl *D) { return true; } 637}; 638 639/// ObjCCategoryDecl - Represents a category declaration. A category allows 640/// you to add methods to an existing class (without subclassing or modifying 641/// the original class interface or implementation:-). Categories don't allow 642/// you to add instance data. The following example adds "myMethod" to all 643/// NSView's within a process: 644/// 645/// @interface NSView (MyViewMethods) 646/// - myMethod; 647/// @end 648/// 649/// Cateogries also allow you to split the implementation of a class across 650/// several files (a feature more naturally supported in C++). 651/// 652/// Categories were originally inspired by dynamic languages such as Common 653/// Lisp and Smalltalk. More traditional class-based languages (C++, Java) 654/// don't support this level of dynamism, which is both powerful and dangerous. 655/// 656class ObjCCategoryDecl : public NamedDecl { 657 /// Interface belonging to this category 658 ObjCInterfaceDecl *ClassInterface; 659 660 /// referenced protocols in this category. 661 ObjCProtocolDecl **ReferencedProtocols; // Null if none 662 unsigned NumReferencedProtocols; // 0 if none 663 664 /// category instance methods 665 ObjCMethodDecl **InstanceMethods; // Null if not defined 666 unsigned NumInstanceMethods; // 0 if none 667 668 /// category class methods 669 ObjCMethodDecl **ClassMethods; // Null if not defined 670 unsigned NumClassMethods; // 0 if not defined 671 672 /// Next category belonging to this class 673 ObjCCategoryDecl *NextClassCategory; 674 675 /// category properties 676 ObjCPropertyDecl **PropertyDecl; // Null if no property 677 unsigned NumPropertyDecl; // 0 if none 678 679 SourceLocation EndLoc; // marks the '>' or identifier. 680 SourceLocation AtEndLoc; // marks the end of the entire interface. 681 682 ObjCCategoryDecl(SourceLocation L, IdentifierInfo *Id) 683 : NamedDecl(ObjCCategory, L, Id), 684 ClassInterface(0), ReferencedProtocols(0), NumReferencedProtocols(0), 685 InstanceMethods(0), NumInstanceMethods(0), 686 ClassMethods(0), NumClassMethods(0), 687 NextClassCategory(0), PropertyDecl(0), NumPropertyDecl(0) { 688 } 689public: 690 691 static ObjCCategoryDecl *Create(ASTContext &C, 692 SourceLocation L, IdentifierInfo *Id); 693 694 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } 695 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } 696 void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; } 697 698 void setReferencedProtocolList(ObjCProtocolDecl **List, unsigned NumRPs); 699 700 void setCatReferencedProtocols(unsigned idx, ObjCProtocolDecl *OID) { 701 assert((idx < NumReferencedProtocols) && "index out of range"); 702 ReferencedProtocols[idx] = OID; 703 } 704 705 ObjCProtocolDecl **getReferencedProtocols() const { 706 return ReferencedProtocols; 707 } 708 unsigned getNumReferencedProtocols() const { return NumReferencedProtocols; } 709 unsigned getNumInstanceMethods() const { return NumInstanceMethods; } 710 unsigned getNumClassMethods() const { return NumClassMethods; } 711 712 void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties); 713 unsigned getNumPropertyDecl() const { return NumPropertyDecl; } 714 715 ObjCPropertyDecl * const * getPropertyDecl() const { return PropertyDecl; } 716 717 typedef ObjCMethodDecl * const * instmeth_iterator; 718 instmeth_iterator instmeth_begin() const { return InstanceMethods; } 719 instmeth_iterator instmeth_end() const { 720 return InstanceMethods+NumInstanceMethods; 721 } 722 723 typedef ObjCMethodDecl * const * classmeth_iterator; 724 classmeth_iterator classmeth_begin() const { return ClassMethods; } 725 classmeth_iterator classmeth_end() const { 726 return ClassMethods+NumClassMethods; 727 } 728 729 // Get the local instance method declared in this interface. 730 ObjCMethodDecl *getInstanceMethod(Selector Sel) { 731 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); 732 I != E; ++I) { 733 if ((*I)->getSelector() == Sel) 734 return *I; 735 } 736 return 0; 737 } 738 // Get the local class method declared in this interface. 739 ObjCMethodDecl *getClassMethod(Selector Sel) { 740 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end(); 741 I != E; ++I) { 742 if ((*I)->getSelector() == Sel) 743 return *I; 744 } 745 return 0; 746 } 747 748 void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers, 749 ObjCMethodDecl **clsMethods, unsigned numClsMembers, 750 SourceLocation AtEndLoc); 751 752 ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; } 753 void insertNextClassCategory() { 754 NextClassCategory = ClassInterface->getCategoryList(); 755 ClassInterface->setCategoryList(this); 756 } 757 // Location information, modeled after the Stmt API. 758 SourceLocation getLocStart() const { return getLocation(); } // '@'interface 759 SourceLocation getLocEnd() const { return EndLoc; } 760 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 761 762 // We also need to record the @end location. 763 SourceLocation getAtEndLoc() const { return AtEndLoc; } 764 765 static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; } 766 static bool classof(const ObjCCategoryDecl *D) { return true; } 767}; 768 769/// ObjCCategoryImplDecl - An object of this class encapsulates a category 770/// @implementation declaration. 771class ObjCCategoryImplDecl : public NamedDecl { 772 /// Class interface for this category implementation 773 ObjCInterfaceDecl *ClassInterface; 774 775 /// implemented instance methods 776 llvm::SmallVector<ObjCMethodDecl*, 32> InstanceMethods; 777 778 /// implemented class methods 779 llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods; 780 781 SourceLocation EndLoc; 782 783 ObjCCategoryImplDecl(SourceLocation L, IdentifierInfo *Id, 784 ObjCInterfaceDecl *classInterface) 785 : NamedDecl(ObjCCategoryImpl, L, Id), ClassInterface(classInterface) {} 786public: 787 static ObjCCategoryImplDecl *Create(ASTContext &C, 788 SourceLocation L, IdentifierInfo *Id, 789 ObjCInterfaceDecl *classInterface); 790 791 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } 792 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } 793 794 unsigned getNumInstanceMethods() const { return InstanceMethods.size(); } 795 unsigned getNumClassMethods() const { return ClassMethods.size(); } 796 797 void addInstanceMethod(ObjCMethodDecl *method) { 798 InstanceMethods.push_back(method); 799 } 800 void addClassMethod(ObjCMethodDecl *method) { 801 ClassMethods.push_back(method); 802 } 803 // Get the instance method definition for this implementation. 804 ObjCMethodDecl *getInstanceMethod(Selector Sel); 805 806 // Get the class method definition for this implementation. 807 ObjCMethodDecl *getClassMethod(Selector Sel); 808 809 typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator 810 instmeth_iterator; 811 instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); } 812 instmeth_iterator instmeth_end() const { return InstanceMethods.end(); } 813 814 typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator 815 classmeth_iterator; 816 classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); } 817 classmeth_iterator classmeth_end() const { return ClassMethods.end(); } 818 819 820 // Location information, modeled after the Stmt API. 821 SourceLocation getLocStart() const { return getLocation(); } 822 SourceLocation getLocEnd() const { return EndLoc; } 823 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 824 825 static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;} 826 static bool classof(const ObjCCategoryImplDecl *D) { return true; } 827}; 828 829/// ObjCImplementationDecl - Represents a class definition - this is where 830/// method definitions are specified. For example: 831/// 832/// @implementation MyClass 833/// - (void)myMethod { /* do something */ } 834/// @end 835/// 836/// Typically, instance variables are specified in the class interface, 837/// *not* in the implemenentation. Nevertheless (for legacy reasons), we 838/// allow instance variables to be specified in the implementation. When 839/// specified, they need to be *identical* to the interface. Now that we 840/// have support for non-fragile ivars in ObjC 2.0, we can consider removing 841/// the legacy semantics and allow developers to move private ivar declarations 842/// from the class interface to the class implementation (but I digress:-) 843/// 844class ObjCImplementationDecl : public NamedDecl { 845 /// Class interface for this implementation 846 ObjCInterfaceDecl *ClassInterface; 847 848 /// Implementation Class's super class. 849 ObjCInterfaceDecl *SuperClass; 850 851 /// Optional Ivars/NumIvars - This is a new[]'d array of pointers to Decls. 852 ObjCIvarDecl **Ivars; // Null if not specified 853 unsigned NumIvars; // 0 if none. 854 855 /// implemented instance methods 856 llvm::SmallVector<ObjCMethodDecl*, 32> InstanceMethods; 857 858 /// implemented class methods 859 llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods; 860 861 SourceLocation EndLoc; 862 863 ObjCImplementationDecl(SourceLocation L, IdentifierInfo *Id, 864 ObjCInterfaceDecl *classInterface, 865 ObjCInterfaceDecl *superDecl) 866 : NamedDecl(ObjCImplementation, L, Id), 867 ClassInterface(classInterface), SuperClass(superDecl), 868 Ivars(0), NumIvars(0) {} 869public: 870 static ObjCImplementationDecl *Create(ASTContext &C, 871 SourceLocation L, IdentifierInfo *Id, 872 ObjCInterfaceDecl *classInterface, 873 ObjCInterfaceDecl *superDecl); 874 875 876 void ObjCAddInstanceVariablesToClassImpl(ObjCIvarDecl **ivars, 877 unsigned numIvars); 878 879 void addInstanceMethod(ObjCMethodDecl *method) { 880 InstanceMethods.push_back(method); 881 } 882 void addClassMethod(ObjCMethodDecl *method) { 883 ClassMethods.push_back(method); 884 } 885 // Location information, modeled after the Stmt API. 886 SourceLocation getLocStart() const { return getLocation(); } 887 SourceLocation getLocEnd() const { return EndLoc; } 888 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 889 890 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } 891 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } 892 const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; } 893 ObjCInterfaceDecl *getSuperClass() { return SuperClass; } 894 895 void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; } 896 897 unsigned getNumInstanceMethods() const { return InstanceMethods.size(); } 898 unsigned getNumClassMethods() const { return ClassMethods.size(); } 899 900 typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator 901 instmeth_iterator; 902 instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); } 903 instmeth_iterator instmeth_end() const { return InstanceMethods.end(); } 904 905 typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator 906 classmeth_iterator; 907 classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); } 908 classmeth_iterator classmeth_end() const { return ClassMethods.end(); } 909 910 // Get the instance method definition for this implementation. 911 ObjCMethodDecl *getInstanceMethod(Selector Sel); 912 913 // Get the class method definition for this implementation. 914 ObjCMethodDecl *getClassMethod(Selector Sel); 915 916 typedef ObjCIvarDecl * const *ivar_iterator; 917 ivar_iterator ivar_begin() const { return Ivars; } 918 ivar_iterator ivar_end() const { return Ivars+NumIvars; } 919 unsigned ivar_size() const { return NumIvars; } 920 bool ivar_empty() const { return NumIvars == 0; } 921 922 static bool classof(const Decl *D) { 923 return D->getKind() == ObjCImplementation; 924 } 925 static bool classof(const ObjCImplementationDecl *D) { return true; } 926}; 927 928/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is 929/// declared as @compatibility_alias alias class. 930class ObjCCompatibleAliasDecl : public NamedDecl { 931 /// Class that this is an alias of. 932 ObjCInterfaceDecl *AliasedClass; 933 934 ObjCCompatibleAliasDecl(SourceLocation L, IdentifierInfo *Id, 935 ObjCInterfaceDecl* aliasedClass) 936 : NamedDecl(ObjCCompatibleAlias, L, Id), AliasedClass(aliasedClass) {} 937public: 938 static ObjCCompatibleAliasDecl *Create(ASTContext &C, 939 SourceLocation L, IdentifierInfo *Id, 940 ObjCInterfaceDecl* aliasedClass); 941 942 const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } 943 ObjCInterfaceDecl *getClassInterface() { return AliasedClass; } 944 945 static bool classof(const Decl *D) { 946 return D->getKind() == ObjCCompatibleAlias; 947 } 948 static bool classof(const ObjCCompatibleAliasDecl *D) { return true; } 949 950}; 951 952/// ObjCPropertyDecl - Represents one property declaration in an interface. 953/// For example: 954/// @property (assign, readwrite) int MyProperty; 955/// 956class ObjCPropertyDecl : public NamedDecl { 957public: 958 enum PropertyAttributeKind { 959 OBJC_PR_noattr = 0x00, 960 OBJC_PR_readonly = 0x01, 961 OBJC_PR_getter = 0x02, 962 OBJC_PR_assign = 0x04, 963 OBJC_PR_readwrite = 0x08, 964 OBJC_PR_retain = 0x10, 965 OBJC_PR_copy = 0x20, 966 OBJC_PR_nonatomic = 0x40, 967 OBJC_PR_setter = 0x80 968 }; 969private: 970 QualType DeclType; 971 unsigned PropertyAttributes : 8; 972 973 IdentifierInfo *GetterName; // getter name of NULL if no getter 974 IdentifierInfo *SetterName; // setter name of NULL if no setter 975 976 ObjCPropertyDecl(SourceLocation L, IdentifierInfo *Id, QualType T) 977 : NamedDecl(ObjCProperty, L, Id), DeclType(T), 978 PropertyAttributes(OBJC_PR_noattr), GetterName(0), SetterName(0) {} 979public: 980 static ObjCPropertyDecl *Create(ASTContext &C, SourceLocation L, 981 IdentifierInfo *Id, QualType T); 982 QualType getType() const { return DeclType; } 983 PropertyAttributeKind getPropertyAttributes() const { 984 return PropertyAttributeKind(PropertyAttributes); 985 } 986 void setPropertyAttributes(PropertyAttributeKind PRVal) { 987 PropertyAttributes |= PRVal; 988 } 989 990 IdentifierInfo *getGetterName() const { return GetterName; } 991 void setGetterName(IdentifierInfo *Id) { GetterName = Id; } 992 993 IdentifierInfo *getSetterName() const { return SetterName; } 994 void setSetterName(IdentifierInfo *Id) { SetterName = Id; } 995 996 static bool classof(const Decl *D) { 997 return D->getKind() == ObjCProperty; 998 } 999 static bool classof(const ObjCPropertyDecl *D) { return true; } 1000}; 1001 1002} // end namespace clang 1003#endif 1004