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