clang API Documentation
00001 //===--- DeclObjC.h - Classes for representing declarations -----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the DeclObjC interface and subclasses. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CLANG_AST_DECLOBJC_H 00015 #define LLVM_CLANG_AST_DECLOBJC_H 00016 00017 #include "clang/AST/Decl.h" 00018 #include "clang/AST/SelectorLocationsKind.h" 00019 #include "llvm/ADT/STLExtras.h" 00020 #include "llvm/Support/Compiler.h" 00021 00022 namespace clang { 00023 class Expr; 00024 class Stmt; 00025 class FunctionDecl; 00026 class RecordDecl; 00027 class ObjCIvarDecl; 00028 class ObjCMethodDecl; 00029 class ObjCProtocolDecl; 00030 class ObjCCategoryDecl; 00031 class ObjCPropertyDecl; 00032 class ObjCPropertyImplDecl; 00033 class CXXCtorInitializer; 00034 00035 class ObjCListBase { 00036 void operator=(const ObjCListBase &); // DO NOT IMPLEMENT 00037 ObjCListBase(const ObjCListBase&); // DO NOT IMPLEMENT 00038 protected: 00039 /// List is an array of pointers to objects that are not owned by this object. 00040 void **List; 00041 unsigned NumElts; 00042 00043 public: 00044 ObjCListBase() : List(0), NumElts(0) {} 00045 unsigned size() const { return NumElts; } 00046 bool empty() const { return NumElts == 0; } 00047 00048 protected: 00049 void set(void *const* InList, unsigned Elts, ASTContext &Ctx); 00050 }; 00051 00052 00053 /// ObjCList - This is a simple template class used to hold various lists of 00054 /// decls etc, which is heavily used by the ObjC front-end. This only use case 00055 /// this supports is setting the list all at once and then reading elements out 00056 /// of it. 00057 template <typename T> 00058 class ObjCList : public ObjCListBase { 00059 public: 00060 void set(T* const* InList, unsigned Elts, ASTContext &Ctx) { 00061 ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx); 00062 } 00063 00064 typedef T* const * iterator; 00065 iterator begin() const { return (iterator)List; } 00066 iterator end() const { return (iterator)List+NumElts; } 00067 00068 T* operator[](unsigned Idx) const { 00069 assert(Idx < NumElts && "Invalid access"); 00070 return (T*)List[Idx]; 00071 } 00072 }; 00073 00074 /// \brief A list of Objective-C protocols, along with the source 00075 /// locations at which they were referenced. 00076 class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> { 00077 SourceLocation *Locations; 00078 00079 using ObjCList<ObjCProtocolDecl>::set; 00080 00081 public: 00082 ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(0) { } 00083 00084 typedef const SourceLocation *loc_iterator; 00085 loc_iterator loc_begin() const { return Locations; } 00086 loc_iterator loc_end() const { return Locations + size(); } 00087 00088 void set(ObjCProtocolDecl* const* InList, unsigned Elts, 00089 const SourceLocation *Locs, ASTContext &Ctx); 00090 }; 00091 00092 00093 /// ObjCMethodDecl - Represents an instance or class method declaration. 00094 /// ObjC methods can be declared within 4 contexts: class interfaces, 00095 /// categories, protocols, and class implementations. While C++ member 00096 /// functions leverage C syntax, Objective-C method syntax is modeled after 00097 /// Smalltalk (using colons to specify argument types/expressions). 00098 /// Here are some brief examples: 00099 /// 00100 /// Setter/getter instance methods: 00101 /// - (void)setMenu:(NSMenu *)menu; 00102 /// - (NSMenu *)menu; 00103 /// 00104 /// Instance method that takes 2 NSView arguments: 00105 /// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView; 00106 /// 00107 /// Getter class method: 00108 /// + (NSMenu *)defaultMenu; 00109 /// 00110 /// A selector represents a unique name for a method. The selector names for 00111 /// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu. 00112 /// 00113 class ObjCMethodDecl : public NamedDecl, public DeclContext { 00114 public: 00115 enum ImplementationControl { None, Required, Optional }; 00116 private: 00117 // The conventional meaning of this method; an ObjCMethodFamily. 00118 // This is not serialized; instead, it is computed on demand and 00119 // cached. 00120 mutable unsigned Family : ObjCMethodFamilyBitWidth; 00121 00122 /// instance (true) or class (false) method. 00123 unsigned IsInstance : 1; 00124 unsigned IsVariadic : 1; 00125 00126 // Synthesized declaration method for a property setter/getter 00127 unsigned IsSynthesized : 1; 00128 00129 // Method has a definition. 00130 unsigned IsDefined : 1; 00131 00132 /// \brief Method redeclaration in the same interface. 00133 unsigned IsRedeclaration : 1; 00134 00135 /// \brief Is redeclared in the same interface. 00136 mutable unsigned HasRedeclaration : 1; 00137 00138 // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum 00139 /// @required/@optional 00140 unsigned DeclImplementation : 2; 00141 00142 // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum 00143 /// in, inout, etc. 00144 unsigned objcDeclQualifier : 6; 00145 00146 /// \brief Indicates whether this method has a related result type. 00147 unsigned RelatedResultType : 1; 00148 00149 /// \brief Whether the locations of the selector identifiers are in a 00150 /// "standard" position, a enum SelectorLocationsKind. 00151 unsigned SelLocsKind : 2; 00152 00153 /// \brief Whether this method overrides any other in the class hierarchy. 00154 /// 00155 /// A method is said to override any method in the class's 00156 /// base classes, its protocols, or its categories' protocols, that has 00157 /// the same selector and is of the same kind (class or instance). 00158 /// A method in an implementation is not considered as overriding the same 00159 /// method in the interface or its categories. 00160 unsigned IsOverriding : 1; 00161 00162 // Result type of this method. 00163 QualType MethodDeclType; 00164 00165 // Type source information for the result type. 00166 TypeSourceInfo *ResultTInfo; 00167 00168 /// \brief Array of ParmVarDecls for the formal parameters of this method 00169 /// and optionally followed by selector locations. 00170 void *ParamsAndSelLocs; 00171 unsigned NumParams; 00172 00173 /// List of attributes for this method declaration. 00174 SourceLocation EndLoc; // the location of the ';' or '}'. 00175 00176 // The following are only used for method definitions, null otherwise. 00177 // FIXME: space savings opportunity, consider a sub-class. 00178 Stmt *Body; 00179 00180 /// SelfDecl - Decl for the implicit self parameter. This is lazily 00181 /// constructed by createImplicitParams. 00182 ImplicitParamDecl *SelfDecl; 00183 /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily 00184 /// constructed by createImplicitParams. 00185 ImplicitParamDecl *CmdDecl; 00186 00187 SelectorLocationsKind getSelLocsKind() const { 00188 return (SelectorLocationsKind)SelLocsKind; 00189 } 00190 bool hasStandardSelLocs() const { 00191 return getSelLocsKind() != SelLoc_NonStandard; 00192 } 00193 00194 /// \brief Get a pointer to the stored selector identifiers locations array. 00195 /// No locations will be stored if HasStandardSelLocs is true. 00196 SourceLocation *getStoredSelLocs() { 00197 return reinterpret_cast<SourceLocation*>(getParams() + NumParams); 00198 } 00199 const SourceLocation *getStoredSelLocs() const { 00200 return reinterpret_cast<const SourceLocation*>(getParams() + NumParams); 00201 } 00202 00203 /// \brief Get a pointer to the stored selector identifiers locations array. 00204 /// No locations will be stored if HasStandardSelLocs is true. 00205 ParmVarDecl **getParams() { 00206 return reinterpret_cast<ParmVarDecl **>(ParamsAndSelLocs); 00207 } 00208 const ParmVarDecl *const *getParams() const { 00209 return reinterpret_cast<const ParmVarDecl *const *>(ParamsAndSelLocs); 00210 } 00211 00212 /// \brief Get the number of stored selector identifiers locations. 00213 /// No locations will be stored if HasStandardSelLocs is true. 00214 unsigned getNumStoredSelLocs() const { 00215 if (hasStandardSelLocs()) 00216 return 0; 00217 return getNumSelectorLocs(); 00218 } 00219 00220 void setParamsAndSelLocs(ASTContext &C, 00221 ArrayRef<ParmVarDecl*> Params, 00222 ArrayRef<SourceLocation> SelLocs); 00223 00224 ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc, 00225 Selector SelInfo, QualType T, 00226 TypeSourceInfo *ResultTInfo, 00227 DeclContext *contextDecl, 00228 bool isInstance = true, 00229 bool isVariadic = false, 00230 bool isSynthesized = false, 00231 bool isImplicitlyDeclared = false, 00232 bool isDefined = false, 00233 ImplementationControl impControl = None, 00234 bool HasRelatedResultType = false) 00235 : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo), 00236 DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily), 00237 IsInstance(isInstance), IsVariadic(isVariadic), 00238 IsSynthesized(isSynthesized), 00239 IsDefined(isDefined), IsRedeclaration(0), HasRedeclaration(0), 00240 DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None), 00241 RelatedResultType(HasRelatedResultType), 00242 SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), 00243 MethodDeclType(T), ResultTInfo(ResultTInfo), 00244 ParamsAndSelLocs(0), NumParams(0), 00245 EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) { 00246 setImplicit(isImplicitlyDeclared); 00247 } 00248 00249 /// \brief A definition will return its interface declaration. 00250 /// An interface declaration will return its definition. 00251 /// Otherwise it will return itself. 00252 virtual ObjCMethodDecl *getNextRedeclaration(); 00253 00254 public: 00255 static ObjCMethodDecl *Create(ASTContext &C, 00256 SourceLocation beginLoc, 00257 SourceLocation endLoc, 00258 Selector SelInfo, 00259 QualType T, 00260 TypeSourceInfo *ResultTInfo, 00261 DeclContext *contextDecl, 00262 bool isInstance = true, 00263 bool isVariadic = false, 00264 bool isSynthesized = false, 00265 bool isImplicitlyDeclared = false, 00266 bool isDefined = false, 00267 ImplementationControl impControl = None, 00268 bool HasRelatedResultType = false); 00269 00270 static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID); 00271 00272 virtual ObjCMethodDecl *getCanonicalDecl(); 00273 const ObjCMethodDecl *getCanonicalDecl() const { 00274 return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl(); 00275 } 00276 00277 ObjCDeclQualifier getObjCDeclQualifier() const { 00278 return ObjCDeclQualifier(objcDeclQualifier); 00279 } 00280 void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; } 00281 00282 /// \brief Determine whether this method has a result type that is related 00283 /// to the message receiver's type. 00284 bool hasRelatedResultType() const { return RelatedResultType; } 00285 00286 /// \brief Note whether this method has a related result type. 00287 void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; } 00288 00289 /// \brief True if this is a method redeclaration in the same interface. 00290 bool isRedeclaration() const { return IsRedeclaration; } 00291 void setAsRedeclaration(const ObjCMethodDecl *PrevMethod); 00292 00293 // Location information, modeled after the Stmt API. 00294 SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); } 00295 SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; } 00296 void setEndLoc(SourceLocation Loc) { EndLoc = Loc; } 00297 virtual SourceRange getSourceRange() const LLVM_READONLY { 00298 return SourceRange(getLocation(), EndLoc); 00299 } 00300 00301 SourceLocation getSelectorStartLoc() const { 00302 if (isImplicit()) 00303 return getLocStart(); 00304 return getSelectorLoc(0); 00305 } 00306 SourceLocation getSelectorLoc(unsigned Index) const { 00307 assert(Index < getNumSelectorLocs() && "Index out of range!"); 00308 if (hasStandardSelLocs()) 00309 return getStandardSelectorLoc(Index, getSelector(), 00310 getSelLocsKind() == SelLoc_StandardWithSpace, 00311 llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()), 00312 NumParams), 00313 EndLoc); 00314 return getStoredSelLocs()[Index]; 00315 } 00316 00317 void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const; 00318 00319 unsigned getNumSelectorLocs() const { 00320 if (isImplicit()) 00321 return 0; 00322 Selector Sel = getSelector(); 00323 if (Sel.isUnarySelector()) 00324 return 1; 00325 return Sel.getNumArgs(); 00326 } 00327 00328 ObjCInterfaceDecl *getClassInterface(); 00329 const ObjCInterfaceDecl *getClassInterface() const { 00330 return const_cast<ObjCMethodDecl*>(this)->getClassInterface(); 00331 } 00332 00333 Selector getSelector() const { return getDeclName().getObjCSelector(); } 00334 00335 QualType getResultType() const { return MethodDeclType; } 00336 void setResultType(QualType T) { MethodDeclType = T; } 00337 00338 /// \brief Determine the type of an expression that sends a message to this 00339 /// function. 00340 QualType getSendResultType() const { 00341 return getResultType().getNonLValueExprType(getASTContext()); 00342 } 00343 00344 TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; } 00345 void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; } 00346 00347 // Iterator access to formal parameters. 00348 unsigned param_size() const { return NumParams; } 00349 typedef const ParmVarDecl *const *param_const_iterator; 00350 typedef ParmVarDecl *const *param_iterator; 00351 param_const_iterator param_begin() const { return getParams(); } 00352 param_const_iterator param_end() const { return getParams() + NumParams; } 00353 param_iterator param_begin() { return getParams(); } 00354 param_iterator param_end() { return getParams() + NumParams; } 00355 // This method returns and of the parameters which are part of the selector 00356 // name mangling requirements. 00357 param_const_iterator sel_param_end() const { 00358 return param_begin() + getSelector().getNumArgs(); 00359 } 00360 00361 /// \brief Sets the method's parameters and selector source locations. 00362 /// If the method is implicit (not coming from source) \arg SelLocs is 00363 /// ignored. 00364 void setMethodParams(ASTContext &C, 00365 ArrayRef<ParmVarDecl*> Params, 00366 ArrayRef<SourceLocation> SelLocs = 00367 ArrayRef<SourceLocation>()); 00368 00369 // Iterator access to parameter types. 00370 typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun; 00371 typedef llvm::mapped_iterator<param_const_iterator, deref_fun> 00372 arg_type_iterator; 00373 00374 arg_type_iterator arg_type_begin() const { 00375 return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType)); 00376 } 00377 arg_type_iterator arg_type_end() const { 00378 return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType)); 00379 } 00380 00381 /// createImplicitParams - Used to lazily create the self and cmd 00382 /// implict parameters. This must be called prior to using getSelfDecl() 00383 /// or getCmdDecl(). The call is ignored if the implicit paramters 00384 /// have already been created. 00385 void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID); 00386 00387 ImplicitParamDecl * getSelfDecl() const { return SelfDecl; } 00388 void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; } 00389 ImplicitParamDecl * getCmdDecl() const { return CmdDecl; } 00390 void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; } 00391 00392 /// Determines the family of this method. 00393 ObjCMethodFamily getMethodFamily() const; 00394 00395 bool isInstanceMethod() const { return IsInstance; } 00396 void setInstanceMethod(bool isInst) { IsInstance = isInst; } 00397 bool isVariadic() const { return IsVariadic; } 00398 void setVariadic(bool isVar) { IsVariadic = isVar; } 00399 00400 bool isClassMethod() const { return !IsInstance; } 00401 00402 bool isSynthesized() const { return IsSynthesized; } 00403 void setSynthesized(bool isSynth) { IsSynthesized = isSynth; } 00404 00405 bool isDefined() const { return IsDefined; } 00406 void setDefined(bool isDefined) { IsDefined = isDefined; } 00407 00408 /// \brief Whether this method overrides any other in the class hierarchy. 00409 /// 00410 /// A method is said to override any method in the class's 00411 /// base classes, its protocols, or its categories' protocols, that has 00412 /// the same selector and is of the same kind (class or instance). 00413 /// A method in an implementation is not considered as overriding the same 00414 /// method in the interface or its categories. 00415 bool isOverriding() const { return IsOverriding; } 00416 void setOverriding(bool isOverriding) { IsOverriding = isOverriding; } 00417 00418 // Related to protocols declared in @protocol 00419 void setDeclImplementation(ImplementationControl ic) { 00420 DeclImplementation = ic; 00421 } 00422 ImplementationControl getImplementationControl() const { 00423 return ImplementationControl(DeclImplementation); 00424 } 00425 00426 virtual Stmt *getBody() const { 00427 return (Stmt*) Body; 00428 } 00429 CompoundStmt *getCompoundBody() { return (CompoundStmt*)Body; } 00430 void setBody(Stmt *B) { Body = B; } 00431 00432 /// \brief Returns whether this specific method is a definition. 00433 bool isThisDeclarationADefinition() const { return Body; } 00434 00435 // Implement isa/cast/dyncast/etc. 00436 static bool classof(const Decl *D) { return classofKind(D->getKind()); } 00437 static bool classof(const ObjCMethodDecl *D) { return true; } 00438 static bool classofKind(Kind K) { return K == ObjCMethod; } 00439 static DeclContext *castToDeclContext(const ObjCMethodDecl *D) { 00440 return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D)); 00441 } 00442 static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) { 00443 return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC)); 00444 } 00445 00446 friend class ASTDeclReader; 00447 friend class ASTDeclWriter; 00448 }; 00449 00450 /// ObjCContainerDecl - Represents a container for method declarations. 00451 /// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl, 00452 /// ObjCProtocolDecl, and ObjCImplDecl. 00453 /// 00454 class ObjCContainerDecl : public NamedDecl, public DeclContext { 00455 virtual void anchor(); 00456 00457 SourceLocation AtStart; 00458 00459 // These two locations in the range mark the end of the method container. 00460 // The first points to the '@' token, and the second to the 'end' token. 00461 SourceRange AtEnd; 00462 public: 00463 00464 ObjCContainerDecl(Kind DK, DeclContext *DC, 00465 IdentifierInfo *Id, SourceLocation nameLoc, 00466 SourceLocation atStartLoc) 00467 : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {} 00468 00469 // Iterator access to properties. 00470 typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator; 00471 prop_iterator prop_begin() const { 00472 return prop_iterator(decls_begin()); 00473 } 00474 prop_iterator prop_end() const { 00475 return prop_iterator(decls_end()); 00476 } 00477 00478 // Iterator access to instance/class methods. 00479 typedef specific_decl_iterator<ObjCMethodDecl> method_iterator; 00480 method_iterator meth_begin() const { 00481 return method_iterator(decls_begin()); 00482 } 00483 method_iterator meth_end() const { 00484 return method_iterator(decls_end()); 00485 } 00486 00487 typedef filtered_decl_iterator<ObjCMethodDecl, 00488 &ObjCMethodDecl::isInstanceMethod> 00489 instmeth_iterator; 00490 instmeth_iterator instmeth_begin() const { 00491 return instmeth_iterator(decls_begin()); 00492 } 00493 instmeth_iterator instmeth_end() const { 00494 return instmeth_iterator(decls_end()); 00495 } 00496 00497 typedef filtered_decl_iterator<ObjCMethodDecl, 00498 &ObjCMethodDecl::isClassMethod> 00499 classmeth_iterator; 00500 classmeth_iterator classmeth_begin() const { 00501 return classmeth_iterator(decls_begin()); 00502 } 00503 classmeth_iterator classmeth_end() const { 00504 return classmeth_iterator(decls_end()); 00505 } 00506 00507 // Get the local instance/class method declared in this interface. 00508 ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const; 00509 ObjCMethodDecl *getInstanceMethod(Selector Sel) const { 00510 return getMethod(Sel, true/*isInstance*/); 00511 } 00512 ObjCMethodDecl *getClassMethod(Selector Sel) const { 00513 return getMethod(Sel, false/*isInstance*/); 00514 } 00515 ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const; 00516 00517 ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; 00518 00519 SourceLocation getAtStartLoc() const { return AtStart; } 00520 void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; } 00521 00522 // Marks the end of the container. 00523 SourceRange getAtEndRange() const { 00524 return AtEnd; 00525 } 00526 void setAtEndRange(SourceRange atEnd) { 00527 AtEnd = atEnd; 00528 } 00529 00530 virtual SourceRange getSourceRange() const LLVM_READONLY { 00531 return SourceRange(AtStart, getAtEndRange().getEnd()); 00532 } 00533 00534 // Implement isa/cast/dyncast/etc. 00535 static bool classof(const Decl *D) { return classofKind(D->getKind()); } 00536 static bool classof(const ObjCContainerDecl *D) { return true; } 00537 static bool classofKind(Kind K) { 00538 return K >= firstObjCContainer && 00539 K <= lastObjCContainer; 00540 } 00541 00542 static DeclContext *castToDeclContext(const ObjCContainerDecl *D) { 00543 return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D)); 00544 } 00545 static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) { 00546 return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC)); 00547 } 00548 }; 00549 00550 /// ObjCInterfaceDecl - Represents an ObjC class declaration. For example: 00551 /// 00552 /// // MostPrimitive declares no super class (not particularly useful). 00553 /// @interface MostPrimitive 00554 /// // no instance variables or methods. 00555 /// @end 00556 /// 00557 /// // NSResponder inherits from NSObject & implements NSCoding (a protocol). 00558 /// @interface NSResponder : NSObject <NSCoding> 00559 /// { // instance variables are represented by ObjCIvarDecl. 00560 /// id nextResponder; // nextResponder instance variable. 00561 /// } 00562 /// - (NSResponder *)nextResponder; // return a pointer to NSResponder. 00563 /// - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer 00564 /// @end // to an NSEvent. 00565 /// 00566 /// Unlike C/C++, forward class declarations are accomplished with @class. 00567 /// Unlike C/C++, @class allows for a list of classes to be forward declared. 00568 /// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes 00569 /// typically inherit from NSObject (an exception is NSProxy). 00570 /// 00571 class ObjCInterfaceDecl : public ObjCContainerDecl 00572 , public Redeclarable<ObjCInterfaceDecl> { 00573 virtual void anchor(); 00574 00575 /// TypeForDecl - This indicates the Type object that represents this 00576 /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType 00577 mutable const Type *TypeForDecl; 00578 friend class ASTContext; 00579 00580 struct DefinitionData { 00581 /// \brief The definition of this class, for quick access from any 00582 /// declaration. 00583 ObjCInterfaceDecl *Definition; 00584 00585 /// Class's super class. 00586 ObjCInterfaceDecl *SuperClass; 00587 00588 /// Protocols referenced in the @interface declaration 00589 ObjCProtocolList ReferencedProtocols; 00590 00591 /// Protocols reference in both the @interface and class extensions. 00592 ObjCList<ObjCProtocolDecl> AllReferencedProtocols; 00593 00594 /// \brief List of categories and class extensions defined for this class. 00595 /// 00596 /// Categories are stored as a linked list in the AST, since the categories 00597 /// and class extensions come long after the initial interface declaration, 00598 /// and we avoid dynamically-resized arrays in the AST wherever possible. 00599 ObjCCategoryDecl *CategoryList; 00600 00601 /// IvarList - List of all ivars defined by this class; including class 00602 /// extensions and implementation. This list is built lazily. 00603 ObjCIvarDecl *IvarList; 00604 00605 /// \brief Indicates that the contents of this Objective-C class will be 00606 /// completed by the external AST source when required. 00607 mutable bool ExternallyCompleted : 1; 00608 00609 /// \brief The location of the superclass, if any. 00610 SourceLocation SuperClassLoc; 00611 00612 /// \brief The location of the last location in this declaration, before 00613 /// the properties/methods. For example, this will be the '>', '}', or 00614 /// identifier, 00615 SourceLocation EndLoc; 00616 00617 DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(), 00618 ExternallyCompleted() { } 00619 }; 00620 00621 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, 00622 SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, 00623 bool isInternal); 00624 00625 void LoadExternalDefinition() const; 00626 00627 /// \brief Contains a pointer to the data associated with this class, 00628 /// which will be NULL if this class has not yet been defined. 00629 DefinitionData *Data; 00630 00631 DefinitionData &data() const { 00632 assert(Data != 0 && "Declaration has no definition!"); 00633 return *Data; 00634 } 00635 00636 /// \brief Allocate the definition data for this class. 00637 void allocateDefinitionData(); 00638 00639 typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base; 00640 virtual ObjCInterfaceDecl *getNextRedeclaration() { 00641 return RedeclLink.getNext(); 00642 } 00643 virtual ObjCInterfaceDecl *getPreviousDeclImpl() { 00644 return getPreviousDecl(); 00645 } 00646 virtual ObjCInterfaceDecl *getMostRecentDeclImpl() { 00647 return getMostRecentDecl(); 00648 } 00649 00650 public: 00651 static ObjCInterfaceDecl *Create(const ASTContext &C, DeclContext *DC, 00652 SourceLocation atLoc, 00653 IdentifierInfo *Id, 00654 ObjCInterfaceDecl *PrevDecl, 00655 SourceLocation ClassLoc = SourceLocation(), 00656 bool isInternal = false); 00657 00658 static ObjCInterfaceDecl *CreateDeserialized(ASTContext &C, unsigned ID); 00659 00660 virtual SourceRange getSourceRange() const LLVM_READONLY { 00661 if (isThisDeclarationADefinition()) 00662 return ObjCContainerDecl::getSourceRange(); 00663 00664 return SourceRange(getAtStartLoc(), getLocation()); 00665 } 00666 00667 /// \brief Indicate that this Objective-C class is complete, but that 00668 /// the external AST source will be responsible for filling in its contents 00669 /// when a complete class is required. 00670 void setExternallyCompleted(); 00671 00672 const ObjCProtocolList &getReferencedProtocols() const { 00673 assert(hasDefinition() && "Caller did not check for forward reference!"); 00674 if (data().ExternallyCompleted) 00675 LoadExternalDefinition(); 00676 00677 return data().ReferencedProtocols; 00678 } 00679 00680 ObjCImplementationDecl *getImplementation() const; 00681 void setImplementation(ObjCImplementationDecl *ImplD); 00682 00683 ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const; 00684 00685 // Get the local instance/class method declared in a category. 00686 ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const; 00687 ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const; 00688 ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const { 00689 return isInstance ? getInstanceMethod(Sel) 00690 : getClassMethod(Sel); 00691 } 00692 00693 typedef ObjCProtocolList::iterator protocol_iterator; 00694 00695 protocol_iterator protocol_begin() const { 00696 // FIXME: Should make sure no callers ever do this. 00697 if (!hasDefinition()) 00698 return protocol_iterator(); 00699 00700 if (data().ExternallyCompleted) 00701 LoadExternalDefinition(); 00702 00703 return data().ReferencedProtocols.begin(); 00704 } 00705 protocol_iterator protocol_end() const { 00706 // FIXME: Should make sure no callers ever do this. 00707 if (!hasDefinition()) 00708 return protocol_iterator(); 00709 00710 if (data().ExternallyCompleted) 00711 LoadExternalDefinition(); 00712 00713 return data().ReferencedProtocols.end(); 00714 } 00715 00716 typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; 00717 00718 protocol_loc_iterator protocol_loc_begin() const { 00719 // FIXME: Should make sure no callers ever do this. 00720 if (!hasDefinition()) 00721 return protocol_loc_iterator(); 00722 00723 if (data().ExternallyCompleted) 00724 LoadExternalDefinition(); 00725 00726 return data().ReferencedProtocols.loc_begin(); 00727 } 00728 00729 protocol_loc_iterator protocol_loc_end() const { 00730 // FIXME: Should make sure no callers ever do this. 00731 if (!hasDefinition()) 00732 return protocol_loc_iterator(); 00733 00734 if (data().ExternallyCompleted) 00735 LoadExternalDefinition(); 00736 00737 return data().ReferencedProtocols.loc_end(); 00738 } 00739 00740 typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator; 00741 00742 all_protocol_iterator all_referenced_protocol_begin() const { 00743 // FIXME: Should make sure no callers ever do this. 00744 if (!hasDefinition()) 00745 return all_protocol_iterator(); 00746 00747 if (data().ExternallyCompleted) 00748 LoadExternalDefinition(); 00749 00750 return data().AllReferencedProtocols.empty() 00751 ? protocol_begin() 00752 : data().AllReferencedProtocols.begin(); 00753 } 00754 all_protocol_iterator all_referenced_protocol_end() const { 00755 // FIXME: Should make sure no callers ever do this. 00756 if (!hasDefinition()) 00757 return all_protocol_iterator(); 00758 00759 if (data().ExternallyCompleted) 00760 LoadExternalDefinition(); 00761 00762 return data().AllReferencedProtocols.empty() 00763 ? protocol_end() 00764 : data().AllReferencedProtocols.end(); 00765 } 00766 00767 typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator; 00768 00769 ivar_iterator ivar_begin() const { 00770 if (const ObjCInterfaceDecl *Def = getDefinition()) 00771 return ivar_iterator(Def->decls_begin()); 00772 00773 // FIXME: Should make sure no callers ever do this. 00774 return ivar_iterator(); 00775 } 00776 ivar_iterator ivar_end() const { 00777 if (const ObjCInterfaceDecl *Def = getDefinition()) 00778 return ivar_iterator(Def->decls_end()); 00779 00780 // FIXME: Should make sure no callers ever do this. 00781 return ivar_iterator(); 00782 } 00783 00784 unsigned ivar_size() const { 00785 return std::distance(ivar_begin(), ivar_end()); 00786 } 00787 00788 bool ivar_empty() const { return ivar_begin() == ivar_end(); } 00789 00790 ObjCIvarDecl *all_declared_ivar_begin(); 00791 const ObjCIvarDecl *all_declared_ivar_begin() const { 00792 // Even though this modifies IvarList, it's conceptually const: 00793 // the ivar chain is essentially a cached property of ObjCInterfaceDecl. 00794 return const_cast<ObjCInterfaceDecl *>(this)->all_declared_ivar_begin(); 00795 } 00796 void setIvarList(ObjCIvarDecl *ivar) { data().IvarList = ivar; } 00797 00798 /// setProtocolList - Set the list of protocols that this interface 00799 /// implements. 00800 void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num, 00801 const SourceLocation *Locs, ASTContext &C) { 00802 data().ReferencedProtocols.set(List, Num, Locs, C); 00803 } 00804 00805 /// mergeClassExtensionProtocolList - Merge class extension's protocol list 00806 /// into the protocol list for this class. 00807 void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List, 00808 unsigned Num, 00809 ASTContext &C); 00810 00811 /// \brief Determine whether this particular declaration of this class is 00812 /// actually also a definition. 00813 bool isThisDeclarationADefinition() const { 00814 return Data && Data->Definition == this; 00815 } 00816 00817 /// \brief Determine whether this class has been defined. 00818 bool hasDefinition() const { return Data; } 00819 00820 /// \brief Retrieve the definition of this class, or NULL if this class 00821 /// has been forward-declared (with @class) but not yet defined (with 00822 /// @interface). 00823 ObjCInterfaceDecl *getDefinition() { 00824 return hasDefinition()? Data->Definition : 0; 00825 } 00826 00827 /// \brief Retrieve the definition of this class, or NULL if this class 00828 /// has been forward-declared (with @class) but not yet defined (with 00829 /// @interface). 00830 const ObjCInterfaceDecl *getDefinition() const { 00831 return hasDefinition()? Data->Definition : 0; 00832 } 00833 00834 /// \brief Starts the definition of this Objective-C class, taking it from 00835 /// a forward declaration (@class) to a definition (@interface). 00836 void startDefinition(); 00837 00838 ObjCInterfaceDecl *getSuperClass() const { 00839 // FIXME: Should make sure no callers ever do this. 00840 if (!hasDefinition()) 00841 return 0; 00842 00843 if (data().ExternallyCompleted) 00844 LoadExternalDefinition(); 00845 00846 return data().SuperClass; 00847 } 00848 00849 void setSuperClass(ObjCInterfaceDecl * superCls) { 00850 data().SuperClass = 00851 (superCls && superCls->hasDefinition()) ? superCls->getDefinition() 00852 : superCls; 00853 } 00854 00855 ObjCCategoryDecl* getCategoryList() const { 00856 // FIXME: Should make sure no callers ever do this. 00857 if (!hasDefinition()) 00858 return 0; 00859 00860 if (data().ExternallyCompleted) 00861 LoadExternalDefinition(); 00862 00863 return data().CategoryList; 00864 } 00865 00866 void setCategoryList(ObjCCategoryDecl *category) { 00867 data().CategoryList = category; 00868 } 00869 00870 ObjCCategoryDecl* getFirstClassExtension() const; 00871 00872 ObjCPropertyDecl 00873 *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const; 00874 00875 /// isSuperClassOf - Return true if this class is the specified class or is a 00876 /// super class of the specified interface class. 00877 bool isSuperClassOf(const ObjCInterfaceDecl *I) const { 00878 // If RHS is derived from LHS it is OK; else it is not OK. 00879 while (I != NULL) { 00880 if (declaresSameEntity(this, I)) 00881 return true; 00882 00883 I = I->getSuperClass(); 00884 } 00885 return false; 00886 } 00887 00888 /// isArcWeakrefUnavailable - Checks for a class or one of its super classes 00889 /// to be incompatible with __weak references. Returns true if it is. 00890 bool isArcWeakrefUnavailable() const { 00891 const ObjCInterfaceDecl *Class = this; 00892 while (Class) { 00893 if (Class->hasAttr<ArcWeakrefUnavailableAttr>()) 00894 return true; 00895 Class = Class->getSuperClass(); 00896 } 00897 return false; 00898 } 00899 00900 /// isObjCRequiresPropertyDefs - Checks that a class or one of its super 00901 /// classes must not be auto-synthesized. Returns class decl. if it must not be; 00902 /// 0, otherwise. 00903 const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const { 00904 const ObjCInterfaceDecl *Class = this; 00905 while (Class) { 00906 if (Class->hasAttr<ObjCRequiresPropertyDefsAttr>()) 00907 return Class; 00908 Class = Class->getSuperClass(); 00909 } 00910 return 0; 00911 } 00912 00913 ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName, 00914 ObjCInterfaceDecl *&ClassDeclared); 00915 ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) { 00916 ObjCInterfaceDecl *ClassDeclared; 00917 return lookupInstanceVariable(IVarName, ClassDeclared); 00918 } 00919 00920 // Lookup a method. First, we search locally. If a method isn't 00921 // found, we search referenced protocols and class categories. 00922 ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance, 00923 bool shallowCategoryLookup= false) const; 00924 ObjCMethodDecl *lookupInstanceMethod(Selector Sel, 00925 bool shallowCategoryLookup = false) const { 00926 return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup); 00927 } 00928 ObjCMethodDecl *lookupClassMethod(Selector Sel, 00929 bool shallowCategoryLookup = false) const { 00930 return lookupMethod(Sel, false/*isInstance*/, shallowCategoryLookup); 00931 } 00932 ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName); 00933 00934 // Lookup a method in the classes implementation hierarchy. 00935 ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel, bool Instance=true); 00936 00937 SourceLocation getEndOfDefinitionLoc() const { 00938 if (!hasDefinition()) 00939 return getLocation(); 00940 00941 return data().EndLoc; 00942 } 00943 00944 void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; } 00945 00946 void setSuperClassLoc(SourceLocation Loc) { data().SuperClassLoc = Loc; } 00947 SourceLocation getSuperClassLoc() const { return data().SuperClassLoc; } 00948 00949 /// isImplicitInterfaceDecl - check that this is an implicitly declared 00950 /// ObjCInterfaceDecl node. This is for legacy objective-c @implementation 00951 /// declaration without an @interface declaration. 00952 bool isImplicitInterfaceDecl() const { 00953 return hasDefinition() ? Data->Definition->isImplicit() : isImplicit(); 00954 } 00955 00956 /// ClassImplementsProtocol - Checks that 'lProto' protocol 00957 /// has been implemented in IDecl class, its super class or categories (if 00958 /// lookupCategory is true). 00959 bool ClassImplementsProtocol(ObjCProtocolDecl *lProto, 00960 bool lookupCategory, 00961 bool RHSIsQualifiedID = false); 00962 00963 typedef redeclarable_base::redecl_iterator redecl_iterator; 00964 using redeclarable_base::redecls_begin; 00965 using redeclarable_base::redecls_end; 00966 using redeclarable_base::getPreviousDecl; 00967 using redeclarable_base::getMostRecentDecl; 00968 00969 /// Retrieves the canonical declaration of this Objective-C class. 00970 ObjCInterfaceDecl *getCanonicalDecl() { 00971 return getFirstDeclaration(); 00972 } 00973 const ObjCInterfaceDecl *getCanonicalDecl() const { 00974 return getFirstDeclaration(); 00975 } 00976 00977 // Low-level accessor 00978 const Type *getTypeForDecl() const { return TypeForDecl; } 00979 void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; } 00980 00981 static bool classof(const Decl *D) { return classofKind(D->getKind()); } 00982 static bool classof(const ObjCInterfaceDecl *D) { return true; } 00983 static bool classofKind(Kind K) { return K == ObjCInterface; } 00984 00985 friend class ASTReader; 00986 friend class ASTDeclReader; 00987 friend class ASTDeclWriter; 00988 }; 00989 00990 /// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC 00991 /// instance variables are identical to C. The only exception is Objective-C 00992 /// supports C++ style access control. For example: 00993 /// 00994 /// @interface IvarExample : NSObject 00995 /// { 00996 /// id defaultToProtected; 00997 /// @public: 00998 /// id canBePublic; // same as C++. 00999 /// @protected: 01000 /// id canBeProtected; // same as C++. 01001 /// @package: 01002 /// id canBePackage; // framework visibility (not available in C++). 01003 /// } 01004 /// 01005 class ObjCIvarDecl : public FieldDecl { 01006 virtual void anchor(); 01007 01008 public: 01009 enum AccessControl { 01010 None, Private, Protected, Public, Package 01011 }; 01012 01013 private: 01014 ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc, 01015 SourceLocation IdLoc, IdentifierInfo *Id, 01016 QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW, 01017 bool synthesized) 01018 : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW, 01019 /*Mutable=*/false, /*HasInit=*/false), 01020 NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {} 01021 01022 public: 01023 static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC, 01024 SourceLocation StartLoc, SourceLocation IdLoc, 01025 IdentifierInfo *Id, QualType T, 01026 TypeSourceInfo *TInfo, 01027 AccessControl ac, Expr *BW = NULL, 01028 bool synthesized=false); 01029 01030 static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID); 01031 01032 /// \brief Return the class interface that this ivar is logically contained 01033 /// in; this is either the interface where the ivar was declared, or the 01034 /// interface the ivar is conceptually a part of in the case of synthesized 01035 /// ivars. 01036 const ObjCInterfaceDecl *getContainingInterface() const; 01037 01038 ObjCIvarDecl *getNextIvar() { return NextIvar; } 01039 const ObjCIvarDecl *getNextIvar() const { return NextIvar; } 01040 void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; } 01041 01042 void setAccessControl(AccessControl ac) { DeclAccess = ac; } 01043 01044 AccessControl getAccessControl() const { return AccessControl(DeclAccess); } 01045 01046 AccessControl getCanonicalAccessControl() const { 01047 return DeclAccess == None ? Protected : AccessControl(DeclAccess); 01048 } 01049 01050 void setSynthesize(bool synth) { Synthesized = synth; } 01051 bool getSynthesize() const { return Synthesized; } 01052 01053 // Implement isa/cast/dyncast/etc. 01054 static bool classof(const Decl *D) { return classofKind(D->getKind()); } 01055 static bool classof(const ObjCIvarDecl *D) { return true; } 01056 static bool classofKind(Kind K) { return K == ObjCIvar; } 01057 private: 01058 /// NextIvar - Next Ivar in the list of ivars declared in class; class's 01059 /// extensions and class's implementation 01060 ObjCIvarDecl *NextIvar; 01061 01062 // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum 01063 unsigned DeclAccess : 3; 01064 unsigned Synthesized : 1; 01065 }; 01066 01067 01068 /// ObjCAtDefsFieldDecl - Represents a field declaration created by an 01069 /// @defs(...). 01070 class ObjCAtDefsFieldDecl : public FieldDecl { 01071 virtual void anchor(); 01072 ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc, 01073 SourceLocation IdLoc, IdentifierInfo *Id, 01074 QualType T, Expr *BW) 01075 : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T, 01076 /*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ? 01077 BW, /*Mutable=*/false, /*HasInit=*/false) {} 01078 01079 public: 01080 static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC, 01081 SourceLocation StartLoc, 01082 SourceLocation IdLoc, IdentifierInfo *Id, 01083 QualType T, Expr *BW); 01084 01085 static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); 01086 01087 // Implement isa/cast/dyncast/etc. 01088 static bool classof(const Decl *D) { return classofKind(D->getKind()); } 01089 static bool classof(const ObjCAtDefsFieldDecl *D) { return true; } 01090 static bool classofKind(Kind K) { return K == ObjCAtDefsField; } 01091 }; 01092 01093 /// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols 01094 /// declare a pure abstract type (i.e no instance variables are permitted). 01095 /// Protocols originally drew inspiration from C++ pure virtual functions (a C++ 01096 /// feature with nice semantics and lousy syntax:-). Here is an example: 01097 /// 01098 /// @protocol NSDraggingInfo <refproto1, refproto2> 01099 /// - (NSWindow *)draggingDestinationWindow; 01100 /// - (NSImage *)draggedImage; 01101 /// @end 01102 /// 01103 /// This says that NSDraggingInfo requires two methods and requires everything 01104 /// that the two "referenced protocols" 'refproto1' and 'refproto2' require as 01105 /// well. 01106 /// 01107 /// @interface ImplementsNSDraggingInfo : NSObject <NSDraggingInfo> 01108 /// @end 01109 /// 01110 /// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and 01111 /// protocols are in distinct namespaces. For example, Cocoa defines both 01112 /// an NSObject protocol and class (which isn't allowed in Java). As a result, 01113 /// protocols are referenced using angle brackets as follows: 01114 /// 01115 /// id <NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo; 01116 /// 01117 class ObjCProtocolDecl : public ObjCContainerDecl, 01118 public Redeclarable<ObjCProtocolDecl> { 01119 virtual void anchor(); 01120 01121 struct DefinitionData { 01122 // \brief The declaration that defines this protocol. 01123 ObjCProtocolDecl *Definition; 01124 01125 /// \brief Referenced protocols 01126 ObjCProtocolList ReferencedProtocols; 01127 }; 01128 01129 DefinitionData *Data; 01130 01131 DefinitionData &data() const { 01132 assert(Data && "Objective-C protocol has no definition!"); 01133 return *Data; 01134 } 01135 01136 ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id, 01137 SourceLocation nameLoc, SourceLocation atStartLoc, 01138 ObjCProtocolDecl *PrevDecl); 01139 01140 void allocateDefinitionData(); 01141 01142 typedef Redeclarable<ObjCProtocolDecl> redeclarable_base; 01143 virtual ObjCProtocolDecl *getNextRedeclaration() { 01144 return RedeclLink.getNext(); 01145 } 01146 virtual ObjCProtocolDecl *getPreviousDeclImpl() { 01147 return getPreviousDecl(); 01148 } 01149 virtual ObjCProtocolDecl *getMostRecentDeclImpl() { 01150 return getMostRecentDecl(); 01151 } 01152 01153 public: 01154 static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC, 01155 IdentifierInfo *Id, 01156 SourceLocation nameLoc, 01157 SourceLocation atStartLoc, 01158 ObjCProtocolDecl *PrevDecl); 01159 01160 static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID); 01161 01162 const ObjCProtocolList &getReferencedProtocols() const { 01163 assert(hasDefinition() && "No definition available!"); 01164 return data().ReferencedProtocols; 01165 } 01166 typedef ObjCProtocolList::iterator protocol_iterator; 01167 protocol_iterator protocol_begin() const { 01168 if (!hasDefinition()) 01169 return protocol_iterator(); 01170 01171 return data().ReferencedProtocols.begin(); 01172 } 01173 protocol_iterator protocol_end() const { 01174 if (!hasDefinition()) 01175 return protocol_iterator(); 01176 01177 return data().ReferencedProtocols.end(); 01178 } 01179 typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; 01180 protocol_loc_iterator protocol_loc_begin() const { 01181 if (!hasDefinition()) 01182 return protocol_loc_iterator(); 01183 01184 return data().ReferencedProtocols.loc_begin(); 01185 } 01186 protocol_loc_iterator protocol_loc_end() const { 01187 if (!hasDefinition()) 01188 return protocol_loc_iterator(); 01189 01190 return data().ReferencedProtocols.loc_end(); 01191 } 01192 unsigned protocol_size() const { 01193 if (!hasDefinition()) 01194 return 0; 01195 01196 return data().ReferencedProtocols.size(); 01197 } 01198 01199 /// setProtocolList - Set the list of protocols that this interface 01200 /// implements. 01201 void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, 01202 const SourceLocation *Locs, ASTContext &C) { 01203 assert(Data && "Protocol is not defined"); 01204 data().ReferencedProtocols.set(List, Num, Locs, C); 01205 } 01206 01207 ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName); 01208 01209 // Lookup a method. First, we search locally. If a method isn't 01210 // found, we search referenced protocols and class categories. 01211 ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const; 01212 ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const { 01213 return lookupMethod(Sel, true/*isInstance*/); 01214 } 01215 ObjCMethodDecl *lookupClassMethod(Selector Sel) const { 01216 return lookupMethod(Sel, false/*isInstance*/); 01217 } 01218 01219 /// \brief Determine whether this protocol has a definition. 01220 bool hasDefinition() const { return Data != 0; } 01221 01222 /// \brief Retrieve the definition of this protocol, if any. 01223 ObjCProtocolDecl *getDefinition() { 01224 return Data? Data->Definition : 0; 01225 } 01226 01227 /// \brief Retrieve the definition of this protocol, if any. 01228 const ObjCProtocolDecl *getDefinition() const { 01229 return Data? Data->Definition : 0; 01230 } 01231 01232 /// \brief Determine whether this particular declaration is also the 01233 /// definition. 01234 bool isThisDeclarationADefinition() const { 01235 return getDefinition() == this; 01236 } 01237 01238 /// \brief Starts the definition of this Objective-C protocol. 01239 void startDefinition(); 01240 01241 virtual SourceRange getSourceRange() const LLVM_READONLY { 01242 if (isThisDeclarationADefinition()) 01243 return ObjCContainerDecl::getSourceRange(); 01244 01245 return SourceRange(getAtStartLoc(), getLocation()); 01246 } 01247 01248 typedef redeclarable_base::redecl_iterator redecl_iterator; 01249 using redeclarable_base::redecls_begin; 01250 using redeclarable_base::redecls_end; 01251 using redeclarable_base::getPreviousDecl; 01252 using redeclarable_base::getMostRecentDecl; 01253 01254 /// Retrieves the canonical declaration of this Objective-C protocol. 01255 ObjCProtocolDecl *getCanonicalDecl() { 01256 return getFirstDeclaration(); 01257 } 01258 const ObjCProtocolDecl *getCanonicalDecl() const { 01259 return getFirstDeclaration(); 01260 } 01261 01262 static bool classof(const Decl *D) { return classofKind(D->getKind()); } 01263 static bool classof(const ObjCProtocolDecl *D) { return true; } 01264 static bool classofKind(Kind K) { return K == ObjCProtocol; } 01265 01266 friend class ASTReader; 01267 friend class ASTDeclReader; 01268 friend class ASTDeclWriter; 01269 }; 01270 01271 /// ObjCCategoryDecl - Represents a category declaration. A category allows 01272 /// you to add methods to an existing class (without subclassing or modifying 01273 /// the original class interface or implementation:-). Categories don't allow 01274 /// you to add instance data. The following example adds "myMethod" to all 01275 /// NSView's within a process: 01276 /// 01277 /// @interface NSView (MyViewMethods) 01278 /// - myMethod; 01279 /// @end 01280 /// 01281 /// Categories also allow you to split the implementation of a class across 01282 /// several files (a feature more naturally supported in C++). 01283 /// 01284 /// Categories were originally inspired by dynamic languages such as Common 01285 /// Lisp and Smalltalk. More traditional class-based languages (C++, Java) 01286 /// don't support this level of dynamism, which is both powerful and dangerous. 01287 /// 01288 class ObjCCategoryDecl : public ObjCContainerDecl { 01289 virtual void anchor(); 01290 01291 /// Interface belonging to this category 01292 ObjCInterfaceDecl *ClassInterface; 01293 01294 /// referenced protocols in this category. 01295 ObjCProtocolList ReferencedProtocols; 01296 01297 /// Next category belonging to this class. 01298 /// FIXME: this should not be a singly-linked list. Move storage elsewhere. 01299 ObjCCategoryDecl *NextClassCategory; 01300 01301 /// true of class extension has at least one bitfield ivar. 01302 bool HasSynthBitfield : 1; 01303 01304 /// \brief The location of the category name in this declaration. 01305 SourceLocation CategoryNameLoc; 01306 01307 /// class extension may have private ivars. 01308 SourceLocation IvarLBraceLoc; 01309 SourceLocation IvarRBraceLoc; 01310 01311 ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc, 01312 SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, 01313 IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, 01314 SourceLocation IvarLBraceLoc=SourceLocation(), 01315 SourceLocation IvarRBraceLoc=SourceLocation()) 01316 : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc), 01317 ClassInterface(IDecl), NextClassCategory(0), HasSynthBitfield(false), 01318 CategoryNameLoc(CategoryNameLoc), 01319 IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) { 01320 } 01321 public: 01322 01323 static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC, 01324 SourceLocation AtLoc, 01325 SourceLocation ClassNameLoc, 01326 SourceLocation CategoryNameLoc, 01327 IdentifierInfo *Id, 01328 ObjCInterfaceDecl *IDecl, 01329 SourceLocation IvarLBraceLoc=SourceLocation(), 01330 SourceLocation IvarRBraceLoc=SourceLocation()); 01331 static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID); 01332 01333 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } 01334 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } 01335 01336 ObjCCategoryImplDecl *getImplementation() const; 01337 void setImplementation(ObjCCategoryImplDecl *ImplD); 01338 01339 /// setProtocolList - Set the list of protocols that this interface 01340 /// implements. 01341 void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, 01342 const SourceLocation *Locs, ASTContext &C) { 01343 ReferencedProtocols.set(List, Num, Locs, C); 01344 } 01345 01346 const ObjCProtocolList &getReferencedProtocols() const { 01347 return ReferencedProtocols; 01348 } 01349 01350 typedef ObjCProtocolList::iterator protocol_iterator; 01351 protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} 01352 protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } 01353 unsigned protocol_size() const { return ReferencedProtocols.size(); } 01354 typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; 01355 protocol_loc_iterator protocol_loc_begin() const { 01356 return ReferencedProtocols.loc_begin(); 01357 } 01358 protocol_loc_iterator protocol_loc_end() const { 01359 return ReferencedProtocols.loc_end(); 01360 } 01361 01362 ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; } 01363 01364 bool IsClassExtension() const { return getIdentifier() == 0; } 01365 const ObjCCategoryDecl *getNextClassExtension() const; 01366 01367 bool hasSynthBitfield() const { return HasSynthBitfield; } 01368 void setHasSynthBitfield (bool val) { HasSynthBitfield = val; } 01369 01370 typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator; 01371 ivar_iterator ivar_begin() const { 01372 return ivar_iterator(decls_begin()); 01373 } 01374 ivar_iterator ivar_end() const { 01375 return ivar_iterator(decls_end()); 01376 } 01377 unsigned ivar_size() const { 01378 return std::distance(ivar_begin(), ivar_end()); 01379 } 01380 bool ivar_empty() const { 01381 return ivar_begin() == ivar_end(); 01382 } 01383 01384 SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; } 01385 void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; } 01386 01387 void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; } 01388 SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; } 01389 void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; } 01390 SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; } 01391 01392 static bool classof(const Decl *D) { return classofKind(D->getKind()); } 01393 static bool classof(const ObjCCategoryDecl *D) { return true; } 01394 static bool classofKind(Kind K) { return K == ObjCCategory; } 01395 01396 friend class ASTDeclReader; 01397 friend class ASTDeclWriter; 01398 }; 01399 01400 class ObjCImplDecl : public ObjCContainerDecl { 01401 virtual void anchor(); 01402 01403 /// Class interface for this class/category implementation 01404 ObjCInterfaceDecl *ClassInterface; 01405 01406 protected: 01407 ObjCImplDecl(Kind DK, DeclContext *DC, 01408 ObjCInterfaceDecl *classInterface, 01409 SourceLocation nameLoc, SourceLocation atStartLoc) 01410 : ObjCContainerDecl(DK, DC, 01411 classInterface? classInterface->getIdentifier() : 0, 01412 nameLoc, atStartLoc), 01413 ClassInterface(classInterface) {} 01414 01415 public: 01416 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } 01417 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } 01418 void setClassInterface(ObjCInterfaceDecl *IFace); 01419 01420 void addInstanceMethod(ObjCMethodDecl *method) { 01421 // FIXME: Context should be set correctly before we get here. 01422 method->setLexicalDeclContext(this); 01423 addDecl(method); 01424 } 01425 void addClassMethod(ObjCMethodDecl *method) { 01426 // FIXME: Context should be set correctly before we get here. 01427 method->setLexicalDeclContext(this); 01428 addDecl(method); 01429 } 01430 01431 void addPropertyImplementation(ObjCPropertyImplDecl *property); 01432 01433 ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const; 01434 ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const; 01435 01436 // Iterator access to properties. 01437 typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator; 01438 propimpl_iterator propimpl_begin() const { 01439 return propimpl_iterator(decls_begin()); 01440 } 01441 propimpl_iterator propimpl_end() const { 01442 return propimpl_iterator(decls_end()); 01443 } 01444 01445 static bool classof(const Decl *D) { return classofKind(D->getKind()); } 01446 static bool classof(const ObjCImplDecl *D) { return true; } 01447 static bool classofKind(Kind K) { 01448 return K >= firstObjCImpl && K <= lastObjCImpl; 01449 } 01450 }; 01451 01452 /// ObjCCategoryImplDecl - An object of this class encapsulates a category 01453 /// @implementation declaration. If a category class has declaration of a 01454 /// property, its implementation must be specified in the category's 01455 /// @implementation declaration. Example: 01456 /// @interface I @end 01457 /// @interface I(CATEGORY) 01458 /// @property int p1, d1; 01459 /// @end 01460 /// @implementation I(CATEGORY) 01461 /// @dynamic p1,d1; 01462 /// @end 01463 /// 01464 /// ObjCCategoryImplDecl 01465 class ObjCCategoryImplDecl : public ObjCImplDecl { 01466 virtual void anchor(); 01467 01468 // Category name 01469 IdentifierInfo *Id; 01470 01471 // Category name location 01472 SourceLocation CategoryNameLoc; 01473 01474 ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id, 01475 ObjCInterfaceDecl *classInterface, 01476 SourceLocation nameLoc, SourceLocation atStartLoc, 01477 SourceLocation CategoryNameLoc) 01478 : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc), 01479 Id(Id), CategoryNameLoc(CategoryNameLoc) {} 01480 public: 01481 static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC, 01482 IdentifierInfo *Id, 01483 ObjCInterfaceDecl *classInterface, 01484 SourceLocation nameLoc, 01485 SourceLocation atStartLoc, 01486 SourceLocation CategoryNameLoc); 01487 static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID); 01488 01489 /// getIdentifier - Get the identifier that names the category 01490 /// interface associated with this implementation. 01491 /// FIXME: This is a bad API, we are overriding the NamedDecl::getIdentifier() 01492 /// to mean something different. For example: 01493 /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier() 01494 /// returns the class interface name, whereas 01495 /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier() 01496 /// returns the category name. 01497 IdentifierInfo *getIdentifier() const { 01498 return Id; 01499 } 01500 void setIdentifier(IdentifierInfo *II) { Id = II; } 01501 01502 ObjCCategoryDecl *getCategoryDecl() const; 01503 01504 SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; } 01505 01506 /// getName - Get the name of identifier for the class interface associated 01507 /// with this implementation as a StringRef. 01508 // 01509 // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean 01510 // something different. 01511 StringRef getName() const { 01512 return Id ? Id->getNameStart() : ""; 01513 } 01514 01515 /// getNameAsCString - Get the name of identifier for the class 01516 /// interface associated with this implementation as a C string 01517 /// (const char*). 01518 // 01519 // FIXME: Deprecated, move clients to getName(). 01520 const char *getNameAsCString() const { 01521 return Id ? Id->getNameStart() : ""; 01522 } 01523 01524 /// @brief Get the name of the class associated with this interface. 01525 // 01526 // FIXME: Deprecated, move clients to getName(). 01527 std::string getNameAsString() const { 01528 return getName(); 01529 } 01530 01531 static bool classof(const Decl *D) { return classofKind(D->getKind()); } 01532 static bool classof(const ObjCCategoryImplDecl *D) { return true; } 01533 static bool classofKind(Kind K) { return K == ObjCCategoryImpl;} 01534 01535 friend class ASTDeclReader; 01536 friend class ASTDeclWriter; 01537 }; 01538 01539 raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID); 01540 01541 /// ObjCImplementationDecl - Represents a class definition - this is where 01542 /// method definitions are specified. For example: 01543 /// 01544 /// @code 01545 /// @implementation MyClass 01546 /// - (void)myMethod { /* do something */ } 01547 /// @end 01548 /// @endcode 01549 /// 01550 /// Typically, instance variables are specified in the class interface, 01551 /// *not* in the implementation. Nevertheless (for legacy reasons), we 01552 /// allow instance variables to be specified in the implementation. When 01553 /// specified, they need to be *identical* to the interface. 01554 /// 01555 class ObjCImplementationDecl : public ObjCImplDecl { 01556 virtual void anchor(); 01557 /// Implementation Class's super class. 01558 ObjCInterfaceDecl *SuperClass; 01559 /// @implementation may have private ivars. 01560 SourceLocation IvarLBraceLoc; 01561 SourceLocation IvarRBraceLoc; 01562 01563 /// Support for ivar initialization. 01564 /// IvarInitializers - The arguments used to initialize the ivars 01565 CXXCtorInitializer **IvarInitializers; 01566 unsigned NumIvarInitializers; 01567 01568 /// true if class has a .cxx_[construct,destruct] method. 01569 bool HasCXXStructors : 1; 01570 01571 /// true of class extension has at least one bitfield ivar. 01572 bool HasSynthBitfield : 1; 01573 01574 ObjCImplementationDecl(DeclContext *DC, 01575 ObjCInterfaceDecl *classInterface, 01576 ObjCInterfaceDecl *superDecl, 01577 SourceLocation nameLoc, SourceLocation atStartLoc, 01578 SourceLocation IvarLBraceLoc=SourceLocation(), 01579 SourceLocation IvarRBraceLoc=SourceLocation()) 01580 : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc), 01581 SuperClass(superDecl), IvarLBraceLoc(IvarLBraceLoc), 01582 IvarRBraceLoc(IvarRBraceLoc), 01583 IvarInitializers(0), NumIvarInitializers(0), 01584 HasCXXStructors(false), HasSynthBitfield(false){} 01585 public: 01586 static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC, 01587 ObjCInterfaceDecl *classInterface, 01588 ObjCInterfaceDecl *superDecl, 01589 SourceLocation nameLoc, 01590 SourceLocation atStartLoc, 01591 SourceLocation IvarLBraceLoc=SourceLocation(), 01592 SourceLocation IvarRBraceLoc=SourceLocation()); 01593 01594 static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID); 01595 01596 /// init_iterator - Iterates through the ivar initializer list. 01597 typedef CXXCtorInitializer **init_iterator; 01598 01599 /// init_const_iterator - Iterates through the ivar initializer list. 01600 typedef CXXCtorInitializer * const * init_const_iterator; 01601 01602 /// init_begin() - Retrieve an iterator to the first initializer. 01603 init_iterator init_begin() { return IvarInitializers; } 01604 /// begin() - Retrieve an iterator to the first initializer. 01605 init_const_iterator init_begin() const { return IvarInitializers; } 01606 01607 /// init_end() - Retrieve an iterator past the last initializer. 01608 init_iterator init_end() { 01609 return IvarInitializers + NumIvarInitializers; 01610 } 01611 /// end() - Retrieve an iterator past the last initializer. 01612 init_const_iterator init_end() const { 01613 return IvarInitializers + NumIvarInitializers; 01614 } 01615 /// getNumArgs - Number of ivars which must be initialized. 01616 unsigned getNumIvarInitializers() const { 01617 return NumIvarInitializers; 01618 } 01619 01620 void setNumIvarInitializers(unsigned numNumIvarInitializers) { 01621 NumIvarInitializers = numNumIvarInitializers; 01622 } 01623 01624 void setIvarInitializers(ASTContext &C, 01625 CXXCtorInitializer ** initializers, 01626 unsigned numInitializers); 01627 01628 bool hasCXXStructors() const { return HasCXXStructors; } 01629 void setHasCXXStructors(bool val) { HasCXXStructors = val; } 01630 01631 bool hasSynthBitfield() const { return HasSynthBitfield; } 01632 void setHasSynthBitfield (bool val) { HasSynthBitfield = val; } 01633 01634 /// getIdentifier - Get the identifier that names the class 01635 /// interface associated with this implementation. 01636 IdentifierInfo *getIdentifier() const { 01637 return getClassInterface()->getIdentifier(); 01638 } 01639 01640 /// getName - Get the name of identifier for the class interface associated 01641 /// with this implementation as a StringRef. 01642 // 01643 // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean 01644 // something different. 01645 StringRef getName() const { 01646 assert(getIdentifier() && "Name is not a simple identifier"); 01647 return getIdentifier()->getName(); 01648 } 01649 01650 /// getNameAsCString - Get the name of identifier for the class 01651 /// interface associated with this implementation as a C string 01652 /// (const char*). 01653 // 01654 // FIXME: Move to StringRef API. 01655 const char *getNameAsCString() const { 01656 return getName().data(); 01657 } 01658 01659 /// @brief Get the name of the class associated with this interface. 01660 // 01661 // FIXME: Move to StringRef API. 01662 std::string getNameAsString() const { 01663 return getName(); 01664 } 01665 01666 const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; } 01667 ObjCInterfaceDecl *getSuperClass() { return SuperClass; } 01668 01669 void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; } 01670 01671 void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; } 01672 SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; } 01673 void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; } 01674 SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; } 01675 01676 typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator; 01677 ivar_iterator ivar_begin() const { 01678 return ivar_iterator(decls_begin()); 01679 } 01680 ivar_iterator ivar_end() const { 01681 return ivar_iterator(decls_end()); 01682 } 01683 unsigned ivar_size() const { 01684 return std::distance(ivar_begin(), ivar_end()); 01685 } 01686 bool ivar_empty() const { 01687 return ivar_begin() == ivar_end(); 01688 } 01689 01690 static bool classof(const Decl *D) { return classofKind(D->getKind()); } 01691 static bool classof(const ObjCImplementationDecl *D) { return true; } 01692 static bool classofKind(Kind K) { return K == ObjCImplementation; } 01693 01694 friend class ASTDeclReader; 01695 friend class ASTDeclWriter; 01696 }; 01697 01698 raw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID); 01699 01700 /// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is 01701 /// declared as @compatibility_alias alias class. 01702 class ObjCCompatibleAliasDecl : public NamedDecl { 01703 virtual void anchor(); 01704 /// Class that this is an alias of. 01705 ObjCInterfaceDecl *AliasedClass; 01706 01707 ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, 01708 ObjCInterfaceDecl* aliasedClass) 01709 : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {} 01710 public: 01711 static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC, 01712 SourceLocation L, IdentifierInfo *Id, 01713 ObjCInterfaceDecl* aliasedClass); 01714 01715 static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C, 01716 unsigned ID); 01717 01718 const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } 01719 ObjCInterfaceDecl *getClassInterface() { return AliasedClass; } 01720 void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; } 01721 01722 static bool classof(const Decl *D) { return classofKind(D->getKind()); } 01723 static bool classof(const ObjCCompatibleAliasDecl *D) { return true; } 01724 static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; } 01725 01726 }; 01727 01728 /// ObjCPropertyDecl - Represents one property declaration in an interface. 01729 /// For example: 01730 /// @property (assign, readwrite) int MyProperty; 01731 /// 01732 class ObjCPropertyDecl : public NamedDecl { 01733 virtual void anchor(); 01734 public: 01735 enum PropertyAttributeKind { 01736 OBJC_PR_noattr = 0x00, 01737 OBJC_PR_readonly = 0x01, 01738 OBJC_PR_getter = 0x02, 01739 OBJC_PR_assign = 0x04, 01740 OBJC_PR_readwrite = 0x08, 01741 OBJC_PR_retain = 0x10, 01742 OBJC_PR_copy = 0x20, 01743 OBJC_PR_nonatomic = 0x40, 01744 OBJC_PR_setter = 0x80, 01745 OBJC_PR_atomic = 0x100, 01746 OBJC_PR_weak = 0x200, 01747 OBJC_PR_strong = 0x400, 01748 OBJC_PR_unsafe_unretained = 0x800 01749 // Adding a property should change NumPropertyAttrsBits 01750 }; 01751 01752 enum { 01753 /// \brief Number of bits fitting all the property attributes. 01754 NumPropertyAttrsBits = 12 01755 }; 01756 01757 enum SetterKind { Assign, Retain, Copy, Weak }; 01758 enum PropertyControl { None, Required, Optional }; 01759 private: 01760 SourceLocation AtLoc; // location of @property 01761 SourceLocation LParenLoc; // location of '(' starting attribute list or null. 01762 TypeSourceInfo *DeclType; 01763 unsigned PropertyAttributes : NumPropertyAttrsBits; 01764 unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits; 01765 // @required/@optional 01766 unsigned PropertyImplementation : 2; 01767 01768 Selector GetterName; // getter name of NULL if no getter 01769 Selector SetterName; // setter name of NULL if no setter 01770 01771 ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method 01772 ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method 01773 ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property 01774 01775 ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, 01776 SourceLocation AtLocation, SourceLocation LParenLocation, 01777 TypeSourceInfo *T) 01778 : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), 01779 LParenLoc(LParenLocation), DeclType(T), 01780 PropertyAttributes(OBJC_PR_noattr), 01781 PropertyAttributesAsWritten(OBJC_PR_noattr), 01782 PropertyImplementation(None), 01783 GetterName(Selector()), 01784 SetterName(Selector()), 01785 GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {} 01786 public: 01787 static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, 01788 SourceLocation L, 01789 IdentifierInfo *Id, SourceLocation AtLocation, 01790 SourceLocation LParenLocation, 01791 TypeSourceInfo *T, 01792 PropertyControl propControl = None); 01793 01794 static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID); 01795 01796 SourceLocation getAtLoc() const { return AtLoc; } 01797 void setAtLoc(SourceLocation L) { AtLoc = L; } 01798 01799 SourceLocation getLParenLoc() const { return LParenLoc; } 01800 void setLParenLoc(SourceLocation L) { LParenLoc = L; } 01801 01802 TypeSourceInfo *getTypeSourceInfo() const { return DeclType; } 01803 QualType getType() const { return DeclType->getType(); } 01804 void setType(TypeSourceInfo *T) { DeclType = T; } 01805 01806 PropertyAttributeKind getPropertyAttributes() const { 01807 return PropertyAttributeKind(PropertyAttributes); 01808 } 01809 void setPropertyAttributes(PropertyAttributeKind PRVal) { 01810 PropertyAttributes |= PRVal; 01811 } 01812 01813 PropertyAttributeKind getPropertyAttributesAsWritten() const { 01814 return PropertyAttributeKind(PropertyAttributesAsWritten); 01815 } 01816 01817 bool hasWrittenStorageAttribute() const { 01818 return PropertyAttributesAsWritten & (OBJC_PR_assign | OBJC_PR_copy | 01819 OBJC_PR_unsafe_unretained | OBJC_PR_retain | OBJC_PR_strong | 01820 OBJC_PR_weak); 01821 } 01822 01823 void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) { 01824 PropertyAttributesAsWritten = PRVal; 01825 } 01826 01827 void makeitReadWriteAttribute(void) { 01828 PropertyAttributes &= ~OBJC_PR_readonly; 01829 PropertyAttributes |= OBJC_PR_readwrite; 01830 } 01831 01832 // Helper methods for accessing attributes. 01833 01834 /// isReadOnly - Return true iff the property has a setter. 01835 bool isReadOnly() const { 01836 return (PropertyAttributes & OBJC_PR_readonly); 01837 } 01838 01839 /// isAtomic - Return true if the property is atomic. 01840 bool isAtomic() const { 01841 return (PropertyAttributes & OBJC_PR_atomic); 01842 } 01843 01844 /// isRetaining - Return true if the property retains its value. 01845 bool isRetaining() const { 01846 return (PropertyAttributes & 01847 (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy)); 01848 } 01849 01850 /// getSetterKind - Return the method used for doing assignment in 01851 /// the property setter. This is only valid if the property has been 01852 /// defined to have a setter. 01853 SetterKind getSetterKind() const { 01854 if (PropertyAttributes & OBJC_PR_strong) 01855 return getType()->isBlockPointerType() ? Copy : Retain; 01856 if (PropertyAttributes & OBJC_PR_retain) 01857 return Retain; 01858 if (PropertyAttributes & OBJC_PR_copy) 01859 return Copy; 01860 if (PropertyAttributes & OBJC_PR_weak) 01861 return Weak; 01862 return Assign; 01863 } 01864 01865 Selector getGetterName() const { return GetterName; } 01866 void setGetterName(Selector Sel) { GetterName = Sel; } 01867 01868 Selector getSetterName() const { return SetterName; } 01869 void setSetterName(Selector Sel) { SetterName = Sel; } 01870 01871 ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; } 01872 void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; } 01873 01874 ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; } 01875 void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; } 01876 01877 // Related to @optional/@required declared in @protocol 01878 void setPropertyImplementation(PropertyControl pc) { 01879 PropertyImplementation = pc; 01880 } 01881 PropertyControl getPropertyImplementation() const { 01882 return PropertyControl(PropertyImplementation); 01883 } 01884 01885 void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { 01886 PropertyIvarDecl = Ivar; 01887 } 01888 ObjCIvarDecl *getPropertyIvarDecl() const { 01889 return PropertyIvarDecl; 01890 } 01891 01892 virtual SourceRange getSourceRange() const LLVM_READONLY { 01893 return SourceRange(AtLoc, getLocation()); 01894 } 01895 01896 /// Lookup a property by name in the specified DeclContext. 01897 static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC, 01898 IdentifierInfo *propertyID); 01899 01900 static bool classof(const Decl *D) { return classofKind(D->getKind()); } 01901 static bool classof(const ObjCPropertyDecl *D) { return true; } 01902 static bool classofKind(Kind K) { return K == ObjCProperty; } 01903 }; 01904 01905 /// ObjCPropertyImplDecl - Represents implementation declaration of a property 01906 /// in a class or category implementation block. For example: 01907 /// @synthesize prop1 = ivar1; 01908 /// 01909 class ObjCPropertyImplDecl : public Decl { 01910 public: 01911 enum Kind { 01912 Synthesize, 01913 Dynamic 01914 }; 01915 private: 01916 SourceLocation AtLoc; // location of @synthesize or @dynamic 01917 01918 /// \brief For @synthesize, the location of the ivar, if it was written in 01919 /// the source code. 01920 /// 01921 /// \code 01922 /// @synthesize int a = b 01923 /// \endcode 01924 SourceLocation IvarLoc; 01925 01926 /// Property declaration being implemented 01927 ObjCPropertyDecl *PropertyDecl; 01928 01929 /// Null for @dynamic. Required for @synthesize. 01930 ObjCIvarDecl *PropertyIvarDecl; 01931 01932 /// Null for @dynamic. Non-null if property must be copy-constructed in getter 01933 Expr *GetterCXXConstructor; 01934 01935 /// Null for @dynamic. Non-null if property has assignment operator to call 01936 /// in Setter synthesis. 01937 Expr *SetterCXXAssignment; 01938 01939 ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L, 01940 ObjCPropertyDecl *property, 01941 Kind PK, 01942 ObjCIvarDecl *ivarDecl, 01943 SourceLocation ivarLoc) 01944 : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc), 01945 IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl), 01946 GetterCXXConstructor(0), SetterCXXAssignment(0) { 01947 assert (PK == Dynamic || PropertyIvarDecl); 01948 } 01949 01950 public: 01951 static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC, 01952 SourceLocation atLoc, SourceLocation L, 01953 ObjCPropertyDecl *property, 01954 Kind PK, 01955 ObjCIvarDecl *ivarDecl, 01956 SourceLocation ivarLoc); 01957 01958 static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID); 01959 01960 virtual SourceRange getSourceRange() const LLVM_READONLY; 01961 01962 SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } 01963 void setAtLoc(SourceLocation Loc) { AtLoc = Loc; } 01964 01965 ObjCPropertyDecl *getPropertyDecl() const { 01966 return PropertyDecl; 01967 } 01968 void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; } 01969 01970 Kind getPropertyImplementation() const { 01971 return PropertyIvarDecl ? Synthesize : Dynamic; 01972 } 01973 01974 ObjCIvarDecl *getPropertyIvarDecl() const { 01975 return PropertyIvarDecl; 01976 } 01977 SourceLocation getPropertyIvarDeclLoc() const { return IvarLoc; } 01978 01979 void setPropertyIvarDecl(ObjCIvarDecl *Ivar, 01980 SourceLocation IvarLoc) { 01981 PropertyIvarDecl = Ivar; 01982 this->IvarLoc = IvarLoc; 01983 } 01984 01985 Expr *getGetterCXXConstructor() const { 01986 return GetterCXXConstructor; 01987 } 01988 void setGetterCXXConstructor(Expr *getterCXXConstructor) { 01989 GetterCXXConstructor = getterCXXConstructor; 01990 } 01991 01992 Expr *getSetterCXXAssignment() const { 01993 return SetterCXXAssignment; 01994 } 01995 void setSetterCXXAssignment(Expr *setterCXXAssignment) { 01996 SetterCXXAssignment = setterCXXAssignment; 01997 } 01998 01999 static bool classof(const Decl *D) { return classofKind(D->getKind()); } 02000 static bool classof(const ObjCPropertyImplDecl *D) { return true; } 02001 static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; } 02002 02003 friend class ASTDeclReader; 02004 }; 02005 02006 } // end namespace clang 02007 #endif