DeclObjC.h revision 60fbca0b027ff5a6579f16cb6e3abab826e0d967
1//===--- DeclObjC.h - Classes for representing declarations -----*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Steve Naroff and is distributed under 6// the University of Illinois Open Source 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/// ObjcInterfaceDecl - Represents an ObjC class declaration. For example: 32/// 33/// // MostPrimitive declares no super class (not particularly useful). 34/// @interface MostPrimitive 35/// // no instance variables or methods. 36/// @end 37/// 38/// // NSResponder inherits from NSObject & implements NSCoding (a protocol). 39/// @interface NSResponder : NSObject <NSCoding> 40/// { // instance variables are represented by ObjcIvarDecl. 41/// id nextResponder; // nextResponder instance variable. 42/// } 43/// - (NSResponder *)nextResponder; // return a pointer to NSResponder. 44/// - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer 45/// @end // to an NSEvent. 46/// 47/// Unlike C/C++, forward class declarations are accomplished with @class. 48/// Unlike C/C++, @class allows for a list of classes to be forward declared. 49/// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes 50/// typically inherit from NSObject (an exception is NSProxy). 51/// 52class ObjcInterfaceDecl : public TypeDecl { 53 54 /// Class's super class. 55 ObjcInterfaceDecl *SuperClass; 56 57 /// Protocols referenced in interface header declaration 58 ObjcProtocolDecl **ReferencedProtocols; // Null if none 59 int NumReferencedProtocols; // -1 if none 60 61 /// Ivars/NumIvars - This is a new[]'d array of pointers to Decls. 62 ObjcIvarDecl **Ivars; // Null if not defined. 63 int NumIvars; // -1 if not defined. 64 65 /// instance methods 66 ObjcMethodDecl **InstanceMethods; // Null if not defined 67 int NumInstanceMethods; // -1 if not defined 68 69 /// class methods 70 ObjcMethodDecl **ClassMethods; // Null if not defined 71 int NumClassMethods; // -1 if not defined 72 73 /// List of categories defined for this class. 74 ObjcCategoryDecl *CategoryList; 75 76 /// class properties 77 ObjcPropertyDecl **PropertyDecl; // Null if no property 78 int NumPropertyDecl; // -1 if no property 79 80 bool ForwardDecl:1; // declared with @class. 81 bool InternalInterface:1; // true - no @interface for @implementation 82 83 SourceLocation EndLoc; // marks the '>', '}', or identifier. 84 SourceLocation AtEndLoc; // marks the end of the entire interface. 85public: 86 ObjcInterfaceDecl(SourceLocation atLoc, unsigned numRefProtos, 87 IdentifierInfo *Id, bool FD = false, 88 bool isInternal = false) 89 : TypeDecl(ObjcInterface, atLoc, Id, 0), SuperClass(0), 90 ReferencedProtocols(0), NumReferencedProtocols(-1), Ivars(0), 91 NumIvars(-1), 92 InstanceMethods(0), NumInstanceMethods(-1), 93 ClassMethods(0), NumClassMethods(-1), 94 CategoryList(0), PropertyDecl(0), NumPropertyDecl(-1), 95 ForwardDecl(FD), InternalInterface(isInternal) { 96 AllocIntfRefProtocols(numRefProtos); 97 } 98 99 // This is necessary when converting a forward declaration to a definition. 100 void AllocIntfRefProtocols(unsigned numRefProtos) { 101 if (numRefProtos) { 102 ReferencedProtocols = new ObjcProtocolDecl*[numRefProtos]; 103 memset(ReferencedProtocols, '\0', 104 numRefProtos*sizeof(ObjcProtocolDecl*)); 105 NumReferencedProtocols = numRefProtos; 106 } 107 } 108 109 ObjcProtocolDecl **getReferencedProtocols() const { 110 return ReferencedProtocols; 111 } 112 int getNumIntfRefProtocols() const { return NumReferencedProtocols; } 113 114 ObjcIvarDecl **getIntfDeclIvars() const { return Ivars; } 115 int getIntfDeclNumIvars() const { return NumIvars; } 116 117 ObjcMethodDecl** getInstanceMethods() const { return InstanceMethods; } 118 int getNumInstanceMethods() const { return NumInstanceMethods; } 119 120 ObjcMethodDecl** getClassMethods() const { return ClassMethods; } 121 int getNumClassMethods() const { return NumClassMethods; } 122 123 void addInstanceVariablesToClass(ObjcIvarDecl **ivars, unsigned numIvars, 124 SourceLocation RBracLoc); 125 126 void addMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, 127 ObjcMethodDecl **clsMethods, unsigned numClsMembers, 128 SourceLocation AtEnd); 129 130 bool isForwardDecl() const { return ForwardDecl; } 131 void setForwardDecl(bool val) { ForwardDecl = val; } 132 133 void setIntfRefProtocols(int idx, ObjcProtocolDecl *OID) { 134 assert((idx < NumReferencedProtocols) && "index out of range"); 135 ReferencedProtocols[idx] = OID; 136 } 137 138 ObjcInterfaceDecl *getSuperClass() const { return SuperClass; } 139 void setSuperClass(ObjcInterfaceDecl * superCls) { SuperClass = superCls; } 140 141 ObjcCategoryDecl* getCategoryList() const { return CategoryList; } 142 void setCategoryList(ObjcCategoryDecl *category) { 143 CategoryList = category; 144 } 145 ObjcMethodDecl *lookupInstanceMethod(Selector &Sel); 146 ObjcMethodDecl *lookupClassMethod(Selector &Sel); 147 148 // Location information, modeled after the Stmt API. 149 SourceLocation getLocStart() const { return getLocation(); } // '@'interface 150 SourceLocation getLocEnd() const { return EndLoc; } 151 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 152 153 // We also need to record the @end location. 154 SourceLocation getAtEndLoc() const { return AtEndLoc; } 155 156 const int getNumPropertyDecl() const { return NumPropertyDecl; } 157 int getNumPropertyDecl() { return NumPropertyDecl; } 158 void setNumPropertyDecl(int num) { NumPropertyDecl = num; } 159 160 ObjcPropertyDecl **const getPropertyDecl() const { return PropertyDecl; } 161 ObjcPropertyDecl **getPropertyDecl() { return PropertyDecl; } 162 void setPropertyDecls(ObjcPropertyDecl **properties) { 163 PropertyDecl = properties; 164 } 165 166 /// ImplicitInterfaceDecl - check that this is an implicitely declared 167 /// ObjcInterfaceDecl node. This is for legacy objective-c @implementation 168 /// declaration without an @interface declaration. 169 bool ImplicitInterfaceDecl() const { return InternalInterface; } 170 171 static bool classof(const Decl *D) { return D->getKind() == ObjcInterface; } 172 static bool classof(const ObjcInterfaceDecl *D) { return true; } 173}; 174 175/// ObjcIvarDecl - Represents an ObjC instance variable. In general, ObjC 176/// instance variables are identical to C. The only exception is Objective-C 177/// supports C++ style access control. For example: 178/// 179/// @interface IvarExample : NSObject 180/// { 181/// id defaultToPrivate; // same as C++. 182/// @public: 183/// id canBePublic; // same as C++. 184/// @protected: 185/// id canBeProtected; // same as C++. 186/// @package: 187/// id canBePackage; // framework visibility (not available in C++). 188/// } 189/// 190class ObjcIvarDecl : public FieldDecl { 191public: 192 ObjcIvarDecl(SourceLocation L, IdentifierInfo *Id, QualType T) 193 : FieldDecl(ObjcIvar, L, Id, T) {} 194 195 enum AccessControl { 196 None, Private, Protected, Public, Package 197 }; 198 void setAccessControl(AccessControl ac) { DeclAccess = ac; } 199 AccessControl getAccessControl() const { return DeclAccess; } 200 201 // Implement isa/cast/dyncast/etc. 202 static bool classof(const Decl *D) { return D->getKind() == ObjcIvar; } 203 static bool classof(const ObjcIvarDecl *D) { return true; } 204private: 205 AccessControl DeclAccess : 3; 206}; 207 208/// ObjcMethodDecl - Represents an instance or class method declaration. 209/// ObjC methods can be declared within 4 contexts: class interfaces, 210/// categories, protocols, and class implementations. While C++ member 211/// functions leverage C syntax, Objective-C method syntax is modeled after 212/// Smalltalk (using colons to specify argument types/expressions). 213/// Here are some brief examples: 214/// 215/// Setter/getter instance methods: 216/// - (void)setMenu:(NSMenu *)menu; 217/// - (NSMenu *)menu; 218/// 219/// Instance method that takes 2 NSView arguments: 220/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView; 221/// 222/// Getter class method: 223/// + (NSMenu *)defaultMenu; 224/// 225/// A selector represents a unique name for a method. The selector names for 226/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu. 227/// 228class ObjcMethodDecl : public Decl { 229public: 230 enum ImplementationControl { None, Required, Optional }; 231private: 232 /// Bitfields must be first fields in this class so they pack with those 233 /// declared in class Decl. 234 /// instance (true) or class (false) method. 235 bool IsInstance : 1; 236 /// @required/@optional 237 ImplementationControl DeclImplementation : 2; 238 239 /// in, inout, etc. 240 ObjcDeclQualifier objcDeclQualifier : 6; 241 242 // @interface decl this Method belongs to. 243 ObjcInterfaceDecl *ClassInterface; 244 245 // A unigue name for this method. 246 Selector SelName; 247 248 // Type of this method. 249 QualType MethodDeclType; 250 /// ParamInfo - new[]'d array of pointers to VarDecls for the formal 251 /// parameters of this Method. This is null if there are no formals. 252 ParmVarDecl **ParamInfo; 253 int NumMethodParams; // -1 if no parameters 254 255 /// List of attributes for this method declaration. 256 AttributeList *MethodAttrs; 257 258 Stmt *Body; // Null if a prototype. 259 260 SourceLocation EndLoc; // the location of the ';' or '{'. 261public: 262 ObjcMethodDecl(SourceLocation beginLoc, SourceLocation endLoc, 263 Selector SelInfo, QualType T, 264 ObjcInterfaceDecl *interfaceDecl, 265 ParmVarDecl **paramInfo = 0, int numParams=-1, 266 AttributeList *M = 0, bool isInstance = true, 267 ImplementationControl impControl = None, 268 Decl *PrevDecl = 0) 269 : Decl(ObjcMethod, beginLoc), 270 IsInstance(isInstance), DeclImplementation(impControl), 271 objcDeclQualifier(OBJC_TQ_None), 272 ClassInterface(interfaceDecl), 273 SelName(SelInfo), MethodDeclType(T), 274 ParamInfo(paramInfo), NumMethodParams(numParams), 275 MethodAttrs(M), EndLoc(endLoc) {} 276 virtual ~ObjcMethodDecl(); 277 278 ObjcDeclQualifier getObjcDeclQualifier() const { return objcDeclQualifier; } 279 void setObjcDeclQualifier(ObjcDeclQualifier QV) { objcDeclQualifier = QV; } 280 281 // Location information, modeled after the Stmt API. 282 SourceLocation getLocStart() const { return getLocation(); } 283 SourceLocation getLocEnd() const { return EndLoc; } 284 285 ObjcInterfaceDecl *const getClassInterface() const { return ClassInterface; } 286 287 Selector getSelector() const { return SelName; } 288 QualType getResultType() const { return MethodDeclType; } 289 290 int getNumParams() const { return NumMethodParams; } 291 ParmVarDecl *getParamDecl(int i) const { 292 assert(i < getNumParams() && "Illegal param #"); 293 return ParamInfo[i]; 294 } 295 void setMethodParams(ParmVarDecl **NewParamInfo, unsigned NumParams); 296 297 AttributeList *getMethodAttrs() const {return MethodAttrs;} 298 bool isInstance() const { return IsInstance; } 299 // Related to protocols declared in @protocol 300 void setDeclImplementation(ImplementationControl ic) 301 { DeclImplementation = ic; } 302 ImplementationControl getImplementationControl() const 303 { return DeclImplementation; } 304 305 Stmt *const getBody() const { return Body; } 306 void setBody(Stmt *B) { Body = B; } 307 308 // Implement isa/cast/dyncast/etc. 309 static bool classof(const Decl *D) { return D->getKind() == ObjcMethod; } 310 static bool classof(const ObjcMethodDecl *D) { return true; } 311}; 312 313/// ObjcProtocolDecl - Represents a protocol declaration. ObjC protocols 314/// declare a pure abstract type (i.e no instance variables are permitted). 315/// Protocols orginally drew inspiration from C++ pure virtual functions (a C++ 316/// feature with nice semantics and lousy syntax:-). Here is an example: 317/// 318/// @protocol NSDraggingInfo 319/// - (NSWindow *)draggingDestinationWindow; 320/// - (NSImage *)draggedImage; 321/// @end 322/// 323/// @interface ImplementsNSDraggingInfo : NSObject <NSDraggingInfo> 324/// @end 325/// 326/// Objc protocols inspired Java interfaces. Unlike Java, ObjC classes and 327/// protocols are in distinct namespaces. For example, Cocoa defines both 328/// an NSObject protocol and class (which isn't allowed in Java). As a result, 329/// protocols are referenced using angle brackets as follows: 330/// 331/// id <NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo; 332/// 333class ObjcProtocolDecl : public NamedDecl { 334 /// referenced protocols 335 ObjcProtocolDecl **ReferencedProtocols; // Null if none 336 int NumReferencedProtocols; // -1 if none 337 338 /// protocol instance methods 339 ObjcMethodDecl **InstanceMethods; // Null if not defined 340 int NumInstanceMethods; // -1 if not defined 341 342 /// protocol class methods 343 ObjcMethodDecl **ClassMethods; // Null if not defined 344 int NumClassMethods; // -1 if not defined 345 346 bool isForwardProtoDecl; // declared with @protocol. 347 348 SourceLocation EndLoc; // marks the '>' or identifier. 349 SourceLocation AtEndLoc; // marks the end of the entire interface. 350public: 351 ObjcProtocolDecl(SourceLocation L, unsigned numRefProtos, 352 IdentifierInfo *Id, bool FD = false) 353 : NamedDecl(ObjcProtocol, L, Id), 354 ReferencedProtocols(0), NumReferencedProtocols(-1), 355 InstanceMethods(0), NumInstanceMethods(-1), 356 ClassMethods(0), NumClassMethods(-1), 357 isForwardProtoDecl(FD) { 358 AllocReferencedProtocols(numRefProtos); 359 } 360 void AllocReferencedProtocols(unsigned numRefProtos) { 361 if (numRefProtos) { 362 ReferencedProtocols = new ObjcProtocolDecl*[numRefProtos]; 363 memset(ReferencedProtocols, '\0', 364 numRefProtos*sizeof(ObjcProtocolDecl*)); 365 NumReferencedProtocols = numRefProtos; 366 } 367 } 368 void addMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, 369 ObjcMethodDecl **clsMethods, unsigned numClsMembers, 370 SourceLocation AtEndLoc); 371 372 void setReferencedProtocols(int idx, ObjcProtocolDecl *OID) { 373 assert((idx < NumReferencedProtocols) && "index out of range"); 374 ReferencedProtocols[idx] = OID; 375 } 376 377 ObjcProtocolDecl** getReferencedProtocols() const { 378 return ReferencedProtocols; 379 } 380 int getNumReferencedProtocols() const { return NumReferencedProtocols; } 381 382 ObjcMethodDecl** getInstanceMethods() const { return InstanceMethods; } 383 int getNumInstanceMethods() const { return NumInstanceMethods; } 384 385 ObjcMethodDecl** getClassMethods() const { return ClassMethods; } 386 int getNumClassMethods() const { return NumClassMethods; } 387 388 bool isForwardDecl() const { return isForwardProtoDecl; } 389 void setForwardDecl(bool val) { isForwardProtoDecl = val; } 390 391 // Location information, modeled after the Stmt API. 392 SourceLocation getLocStart() const { return getLocation(); } // '@'protocol 393 SourceLocation getLocEnd() const { return EndLoc; } 394 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 395 396 // We also need to record the @end location. 397 SourceLocation getAtEndLoc() const { return AtEndLoc; } 398 399 static bool classof(const Decl *D) { return D->getKind() == ObjcProtocol; } 400 static bool classof(const ObjcProtocolDecl *D) { return true; } 401}; 402 403/// ObjcClassDecl - Specifies a list of forward class declarations. For example: 404/// 405/// @class NSCursor, NSImage, NSPasteboard, NSWindow; 406/// 407class ObjcClassDecl : public Decl { 408 ObjcInterfaceDecl **ForwardDecls; 409 unsigned NumForwardDecls; 410public: 411 ObjcClassDecl(SourceLocation L, ObjcInterfaceDecl **Elts, unsigned nElts) 412 : Decl(ObjcClass, L) { 413 if (nElts) { 414 ForwardDecls = new ObjcInterfaceDecl*[nElts]; 415 memcpy(ForwardDecls, Elts, nElts*sizeof(ObjcInterfaceDecl*)); 416 } else { 417 ForwardDecls = 0; 418 } 419 NumForwardDecls = nElts; 420 } 421 void setInterfaceDecl(unsigned idx, ObjcInterfaceDecl *OID) { 422 assert(idx < NumForwardDecls && "index out of range"); 423 ForwardDecls[idx] = OID; 424 } 425 ObjcInterfaceDecl** getForwardDecls() const { return ForwardDecls; } 426 int getNumForwardDecls() const { return NumForwardDecls; } 427 428 static bool classof(const Decl *D) { return D->getKind() == ObjcClass; } 429 static bool classof(const ObjcClassDecl *D) { return true; } 430}; 431 432/// ObjcForwardProtocolDecl - Specifies a list of forward protocol declarations. 433/// For example: 434/// 435/// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo; 436/// 437class ObjcForwardProtocolDecl : public Decl { 438 ObjcProtocolDecl **ReferencedProtocols; 439 unsigned NumReferencedProtocols; 440public: 441 ObjcForwardProtocolDecl(SourceLocation L, 442 ObjcProtocolDecl **Elts, unsigned nElts) 443 : Decl(ObjcForwardProtocol, L) { 444 NumReferencedProtocols = nElts; 445 if (nElts) { 446 ReferencedProtocols = new ObjcProtocolDecl*[nElts]; 447 memcpy(ReferencedProtocols, Elts, nElts*sizeof(ObjcProtocolDecl*)); 448 } else { 449 ReferencedProtocols = 0; 450 } 451 } 452 void setForwardProtocolDecl(unsigned idx, ObjcProtocolDecl *OID) { 453 assert(idx < NumReferencedProtocols && "index out of range"); 454 ReferencedProtocols[idx] = OID; 455 } 456 457 unsigned getNumForwardDecls() const { return NumReferencedProtocols; } 458 459 ObjcProtocolDecl *getForwardProtocolDecl(unsigned idx) { 460 assert(idx < NumReferencedProtocols && "index out of range"); 461 return ReferencedProtocols[idx]; 462 } 463 const ObjcProtocolDecl *getForwardProtocolDecl(unsigned idx) const { 464 assert(idx < NumReferencedProtocols && "index out of range"); 465 return ReferencedProtocols[idx]; 466 } 467 468 static bool classof(const Decl *D) { 469 return D->getKind() == ObjcForwardProtocol; 470 } 471 static bool classof(const ObjcForwardProtocolDecl *D) { return true; } 472}; 473 474/// ObjcCategoryDecl - Represents a category declaration. A category allows 475/// you to add methods to an existing class (without subclassing or modifying 476/// the original class interface or implementation:-). Categories don't allow 477/// you to add instance data. The following example adds "myMethod" to all 478/// NSView's within a process: 479/// 480/// @interface NSView (MyViewMethods) 481/// - myMethod; 482/// @end 483/// 484/// Cateogries also allow you to split the implementation of a class across 485/// several files (a feature more naturally supported in C++). 486/// 487/// Categories were originally inspired by dynamic languages such as Common 488/// Lisp and Smalltalk. More traditional class-based languages (C++, Java) 489/// don't support this level of dynamism, which is both powerful and dangerous. 490/// 491class ObjcCategoryDecl : public NamedDecl { 492 /// Interface belonging to this category 493 ObjcInterfaceDecl *ClassInterface; 494 495 /// referenced protocols in this category 496 ObjcProtocolDecl **ReferencedProtocols; // Null if none 497 int NumReferencedProtocols; // -1 if none 498 499 /// category instance methods 500 ObjcMethodDecl **InstanceMethods; // Null if not defined 501 int NumInstanceMethods; // -1 if not defined 502 503 /// category class methods 504 ObjcMethodDecl **ClassMethods; // Null if not defined 505 int NumClassMethods; // -1 if not defined 506 507 /// Next category belonging to this class 508 ObjcCategoryDecl *NextClassCategory; 509 510 SourceLocation EndLoc; // marks the '>' or identifier. 511 SourceLocation AtEndLoc; // marks the end of the entire interface. 512public: 513 ObjcCategoryDecl(SourceLocation L, unsigned numRefProtocol,IdentifierInfo *Id) 514 : NamedDecl(ObjcCategory, L, Id), 515 ClassInterface(0), ReferencedProtocols(0), NumReferencedProtocols(-1), 516 InstanceMethods(0), NumInstanceMethods(-1), 517 ClassMethods(0), NumClassMethods(-1), 518 NextClassCategory(0) { 519 if (numRefProtocol) { 520 ReferencedProtocols = new ObjcProtocolDecl*[numRefProtocol]; 521 memset(ReferencedProtocols, '\0', 522 numRefProtocol*sizeof(ObjcProtocolDecl*)); 523 NumReferencedProtocols = numRefProtocol; 524 } 525 } 526 527 ObjcInterfaceDecl *getClassInterface() const { return ClassInterface; } 528 void setClassInterface(ObjcInterfaceDecl *IDecl) { ClassInterface = IDecl; } 529 530 void setCatReferencedProtocols(int idx, ObjcProtocolDecl *OID) { 531 assert((idx < NumReferencedProtocols) && "index out of range"); 532 ReferencedProtocols[idx] = OID; 533 } 534 535 ObjcProtocolDecl **getReferencedProtocols() const { 536 return ReferencedProtocols; 537 } 538 int getNumReferencedProtocols() const { return NumReferencedProtocols; } 539 540 ObjcMethodDecl **getInstanceMethods() const { return InstanceMethods; } 541 int getNumInstanceMethods() const { return NumInstanceMethods; } 542 543 ObjcMethodDecl **getClassMethods() const { return ClassMethods; } 544 int getNumClassMethods() const { return NumClassMethods; } 545 546 void addMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, 547 ObjcMethodDecl **clsMethods, unsigned numClsMembers, 548 SourceLocation AtEndLoc); 549 550 ObjcCategoryDecl *getNextClassCategory() const { return NextClassCategory; } 551 void insertNextClassCategory() { 552 NextClassCategory = ClassInterface->getCategoryList(); 553 ClassInterface->setCategoryList(this); 554 } 555 // Location information, modeled after the Stmt API. 556 SourceLocation getLocStart() const { return getLocation(); } // '@'interface 557 SourceLocation getLocEnd() const { return EndLoc; } 558 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 559 560 // We also need to record the @end location. 561 SourceLocation getAtEndLoc() const { return AtEndLoc; } 562 563 static bool classof(const Decl *D) { return D->getKind() == ObjcCategory; } 564 static bool classof(const ObjcCategoryDecl *D) { return true; } 565}; 566 567/// ObjcCategoryImplDecl - An object of this class encapsulates a category 568/// @implementation declaration. 569class ObjcCategoryImplDecl : public NamedDecl { 570 /// Class interface for this category implementation 571 ObjcInterfaceDecl *ClassInterface; 572 573 /// category instance methods being implemented 574 ObjcMethodDecl **InstanceMethods; // Null if category is not implementing any 575 int NumInstanceMethods; // -1 if category is not implementing any 576 577 /// category class methods being implemented 578 ObjcMethodDecl **ClassMethods; // Null if category is not implementing any 579 int NumClassMethods; // -1 if category is not implementing any 580 581 public: 582 ObjcCategoryImplDecl(SourceLocation L, IdentifierInfo *Id, 583 ObjcInterfaceDecl *classInterface) 584 : NamedDecl(ObjcCategoryImpl, L, Id), 585 ClassInterface(classInterface), 586 InstanceMethods(0), NumInstanceMethods(-1), 587 ClassMethods(0), NumClassMethods(-1) {} 588 589 ObjcInterfaceDecl *getClassInterface() const { 590 return ClassInterface; 591 } 592 593 ObjcMethodDecl **getInstanceMethods() const { return InstanceMethods; } 594 int getNumInstanceMethods() const { return NumInstanceMethods; } 595 596 ObjcMethodDecl **getClassMethods() const { return ClassMethods; } 597 int getNumClassMethods() const { return NumClassMethods; } 598 599 void addMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, 600 ObjcMethodDecl **clsMethods, unsigned numClsMembers, 601 SourceLocation AtEndLoc); 602 603 static bool classof(const Decl *D) { return D->getKind() == ObjcCategoryImpl;} 604 static bool classof(const ObjcCategoryImplDecl *D) { return true; } 605}; 606 607/// ObjcImplementationDecl - Represents a class definition - this is where 608/// method definitions are specified. For example: 609/// 610/// @implementation MyClass 611/// - (void)myMethod { /* do something */ } 612/// @end 613/// 614/// Typically, instance variables are specified in the class interface, 615/// *not* in the implemenentation. Nevertheless (for legacy reasons), we 616/// allow instance variables to be specified in the implementation. When 617/// specified, they need to be *identical* to the interface. Now that we 618/// have support for non-fragile ivars in ObjC 2.0, we can consider removing 619/// the legacy semantics and allow developers to move private ivar declarations 620/// from the class interface to the class implementation (but I digress:-) 621/// 622class ObjcImplementationDecl : public NamedDecl { 623 /// Class interface for this category implementation 624 ObjcInterfaceDecl *ClassInterface; 625 626 /// Implementation Class's super class. 627 ObjcInterfaceDecl *SuperClass; 628 629 /// Optional Ivars/NumIvars - This is a new[]'d array of pointers to Decls. 630 ObjcIvarDecl **Ivars; // Null if not specified 631 int NumIvars; // -1 if not defined. 632 633 /// implemented instance methods 634 ObjcMethodDecl **InstanceMethods; // Null if not defined 635 int NumInstanceMethods; // -1 if not defined 636 637 /// implemented class methods 638 ObjcMethodDecl **ClassMethods; // Null if not defined 639 int NumClassMethods; // -1 if not defined 640 641public: 642 ObjcImplementationDecl(SourceLocation L, IdentifierInfo *Id, 643 ObjcInterfaceDecl *classInterface, 644 ObjcInterfaceDecl *superDecl) 645 : NamedDecl(ObjcImplementation, L, Id), 646 ClassInterface(classInterface), 647 SuperClass(superDecl), 648 Ivars(0), NumIvars(-1), 649 InstanceMethods(0), NumInstanceMethods(-1), 650 ClassMethods(0), NumClassMethods(-1) {} 651 652 void ObjcAddInstanceVariablesToClassImpl(ObjcIvarDecl **ivars, 653 unsigned numIvars); 654 655 void addMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, 656 ObjcMethodDecl **clsMethods, unsigned numClsMembers, 657 SourceLocation AtEndLoc); 658 659 ObjcInterfaceDecl *getClassInterface() const { return ClassInterface; } 660 ObjcInterfaceDecl *getSuperClass() const { return SuperClass; } 661 662 void setSuperClass(ObjcInterfaceDecl * superCls) 663 { SuperClass = superCls; } 664 665 ObjcMethodDecl **getInstanceMethods() const { return InstanceMethods; } 666 int getNumInstanceMethods() const { return NumInstanceMethods; } 667 668 ObjcMethodDecl **getClassMethods() const { return ClassMethods; } 669 int getNumClassMethods() const { return NumClassMethods; } 670 671 ObjcIvarDecl **getImplDeclIVars() const { return Ivars; } 672 int getImplDeclNumIvars() const { return NumIvars; } 673 674 static bool classof(const Decl *D) { 675 return D->getKind() == ObjcImplementation; 676 } 677 static bool classof(const ObjcImplementationDecl *D) { return true; } 678}; 679 680/// ObjcCompatibleAliasDecl - Represents alias of a class. This alias is 681/// declared as @compatibility_alias alias class. 682class ObjcCompatibleAliasDecl : public ScopedDecl { 683 /// Class that this is an alias of. 684 ObjcInterfaceDecl *AliasedClass; 685 686public: 687 ObjcCompatibleAliasDecl(SourceLocation L, IdentifierInfo *Id, 688 ObjcInterfaceDecl* aliasedClass) 689 : ScopedDecl(CompatibleAlias, L, Id, 0), 690 AliasedClass(aliasedClass) {} 691 692 ObjcInterfaceDecl *getClassInterface() const { return AliasedClass; } 693 694 static bool classof(const Decl *D) { 695 return D->getKind() == CompatibleAlias; 696 } 697 static bool classof(const ObjcCompatibleAliasDecl *D) { return true; } 698 699}; 700 701class ObjcPropertyDecl : public Decl { 702public: 703 enum PropertyAttributeKind { OBJC_PR_noattr = 0x0, 704 OBJC_PR_readonly = 0x01, 705 OBJC_PR_getter = 0x02, 706 OBJC_PR_assign = 0x04, 707 OBJC_PR_readwrite = 0x08, 708 OBJC_PR_retain = 0x10, 709 OBJC_PR_copy = 0x20, 710 OBJC_PR_nonatomic = 0x40, 711 OBJC_PR_setter = 0x80 }; 712private: 713 // List of property name declarations 714 // FIXME: Property is not an ivar. 715 ObjcIvarDecl **PropertyDecls; 716 int NumPropertyDecls; 717 718 PropertyAttributeKind PropertyAttributes : 8; 719 720 IdentifierInfo *GetterName; // getter name of NULL if no getter 721 IdentifierInfo *SetterName; // setter name of NULL if no setter 722 723public: 724 ObjcPropertyDecl(SourceLocation L) 725 : Decl(PropertyDecl, L), 726 PropertyDecls(0), NumPropertyDecls(-1), PropertyAttributes(OBJC_PR_noattr), 727 GetterName(0), SetterName(0) {} 728 729 ObjcIvarDecl **const getPropertyDecls() const { return PropertyDecls; } 730 void setPropertyDecls(ObjcIvarDecl **property) { PropertyDecls = property; } 731 732 const int getNumPropertyDecls() const { return NumPropertyDecls; } 733 void setNumPropertyDecls(int num) { NumPropertyDecls = num; } 734 735 const PropertyAttributeKind getPropertyAttributes() const 736 { return PropertyAttributes; } 737 void setPropertyAttributes(PropertyAttributeKind PRVal) { 738 PropertyAttributes = 739 (PropertyAttributeKind) (PropertyAttributes | PRVal); 740 } 741 742 const IdentifierInfo *getGetterName() const { return GetterName; } 743 IdentifierInfo *getGetterName() { return GetterName; } 744 void setGetterName(IdentifierInfo *Id) { GetterName = Id; } 745 746 const IdentifierInfo *getSetterName() const { return SetterName; } 747 IdentifierInfo *getSetterName() { return SetterName; } 748 void setSetterName(IdentifierInfo *Id) { SetterName = Id; } 749 750 static bool classof(const Decl *D) { 751 return D->getKind() == PropertyDecl; 752 } 753 static bool classof(const ObjcPropertyDecl *D) { return true; } 754}; 755 756} // end namespace clang 757#endif 758