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