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