1 //===--- DeclObjC.h - Classes for representing declarations -----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the DeclObjC interface and subclasses.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_DECLOBJC_H
15 #define LLVM_CLANG_AST_DECLOBJC_H
17 #include "clang/AST/Decl.h"
18 #include "clang/AST/SelectorLocationsKind.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/Support/Compiler.h"
29 class ObjCProtocolDecl;
30 class ObjCCategoryDecl;
31 class ObjCPropertyDecl;
32 class ObjCPropertyImplDecl;
33 class CXXCtorInitializer;
36 ObjCListBase(const ObjCListBase &) LLVM_DELETED_FUNCTION;
37 void operator=(const ObjCListBase &) LLVM_DELETED_FUNCTION;
39 /// List is an array of pointers to objects that are not owned by this object.
44 ObjCListBase() : List(0), NumElts(0) {}
45 unsigned size() const { return NumElts; }
46 bool empty() const { return NumElts == 0; }
49 void set(void *const* InList, unsigned Elts, ASTContext &Ctx);
53 /// ObjCList - This is a simple template class used to hold various lists of
54 /// decls etc, which is heavily used by the ObjC front-end. This only use case
55 /// this supports is setting the list all at once and then reading elements out
58 class ObjCList : public ObjCListBase {
60 void set(T* const* InList, unsigned Elts, ASTContext &Ctx) {
61 ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx);
64 typedef T* const * iterator;
65 iterator begin() const { return (iterator)List; }
66 iterator end() const { return (iterator)List+NumElts; }
68 T* operator[](unsigned Idx) const {
69 assert(Idx < NumElts && "Invalid access");
74 /// \brief A list of Objective-C protocols, along with the source
75 /// locations at which they were referenced.
76 class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> {
77 SourceLocation *Locations;
79 using ObjCList<ObjCProtocolDecl>::set;
82 ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(0) { }
84 typedef const SourceLocation *loc_iterator;
85 loc_iterator loc_begin() const { return Locations; }
86 loc_iterator loc_end() const { return Locations + size(); }
88 void set(ObjCProtocolDecl* const* InList, unsigned Elts,
89 const SourceLocation *Locs, ASTContext &Ctx);
93 /// ObjCMethodDecl - Represents an instance or class method declaration.
94 /// ObjC methods can be declared within 4 contexts: class interfaces,
95 /// categories, protocols, and class implementations. While C++ member
96 /// functions leverage C syntax, Objective-C method syntax is modeled after
97 /// Smalltalk (using colons to specify argument types/expressions).
98 /// Here are some brief examples:
100 /// Setter/getter instance methods:
101 /// - (void)setMenu:(NSMenu *)menu;
102 /// - (NSMenu *)menu;
104 /// Instance method that takes 2 NSView arguments:
105 /// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
107 /// Getter class method:
108 /// + (NSMenu *)defaultMenu;
110 /// A selector represents a unique name for a method. The selector names for
111 /// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
113 class ObjCMethodDecl : public NamedDecl, public DeclContext {
115 enum ImplementationControl { None, Required, Optional };
117 // The conventional meaning of this method; an ObjCMethodFamily.
118 // This is not serialized; instead, it is computed on demand and
120 mutable unsigned Family : ObjCMethodFamilyBitWidth;
122 /// instance (true) or class (false) method.
123 unsigned IsInstance : 1;
124 unsigned IsVariadic : 1;
126 /// True if this method is the getter or setter for an explicit property.
127 unsigned IsPropertyAccessor : 1;
129 // Method has a definition.
130 unsigned IsDefined : 1;
132 /// \brief Method redeclaration in the same interface.
133 unsigned IsRedeclaration : 1;
135 /// \brief Is redeclared in the same interface.
136 mutable unsigned HasRedeclaration : 1;
138 // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
139 /// \@required/\@optional
140 unsigned DeclImplementation : 2;
142 // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
144 unsigned objcDeclQualifier : 6;
146 /// \brief Indicates whether this method has a related result type.
147 unsigned RelatedResultType : 1;
149 /// \brief Whether the locations of the selector identifiers are in a
150 /// "standard" position, a enum SelectorLocationsKind.
151 unsigned SelLocsKind : 2;
153 /// \brief Whether this method overrides any other in the class hierarchy.
155 /// A method is said to override any method in the class's
156 /// base classes, its protocols, or its categories' protocols, that has
157 /// the same selector and is of the same kind (class or instance).
158 /// A method in an implementation is not considered as overriding the same
159 /// method in the interface or its categories.
160 unsigned IsOverriding : 1;
162 // Result type of this method.
163 QualType MethodDeclType;
165 // Type source information for the result type.
166 TypeSourceInfo *ResultTInfo;
168 /// \brief Array of ParmVarDecls for the formal parameters of this method
169 /// and optionally followed by selector locations.
170 void *ParamsAndSelLocs;
173 /// List of attributes for this method declaration.
174 SourceLocation DeclEndLoc; // the location of the ';' or '{'.
176 // The following are only used for method definitions, null otherwise.
177 LazyDeclStmtPtr Body;
179 /// SelfDecl - Decl for the implicit self parameter. This is lazily
180 /// constructed by createImplicitParams.
181 ImplicitParamDecl *SelfDecl;
182 /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily
183 /// constructed by createImplicitParams.
184 ImplicitParamDecl *CmdDecl;
186 SelectorLocationsKind getSelLocsKind() const {
187 return (SelectorLocationsKind)SelLocsKind;
189 bool hasStandardSelLocs() const {
190 return getSelLocsKind() != SelLoc_NonStandard;
193 /// \brief Get a pointer to the stored selector identifiers locations array.
194 /// No locations will be stored if HasStandardSelLocs is true.
195 SourceLocation *getStoredSelLocs() {
196 return reinterpret_cast<SourceLocation*>(getParams() + NumParams);
198 const SourceLocation *getStoredSelLocs() const {
199 return reinterpret_cast<const SourceLocation*>(getParams() + NumParams);
202 /// \brief Get a pointer to the stored selector identifiers locations array.
203 /// No locations will be stored if HasStandardSelLocs is true.
204 ParmVarDecl **getParams() {
205 return reinterpret_cast<ParmVarDecl **>(ParamsAndSelLocs);
207 const ParmVarDecl *const *getParams() const {
208 return reinterpret_cast<const ParmVarDecl *const *>(ParamsAndSelLocs);
211 /// \brief Get the number of stored selector identifiers locations.
212 /// No locations will be stored if HasStandardSelLocs is true.
213 unsigned getNumStoredSelLocs() const {
214 if (hasStandardSelLocs())
216 return getNumSelectorLocs();
219 void setParamsAndSelLocs(ASTContext &C,
220 ArrayRef<ParmVarDecl*> Params,
221 ArrayRef<SourceLocation> SelLocs);
223 ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
224 Selector SelInfo, QualType T,
225 TypeSourceInfo *ResultTInfo,
226 DeclContext *contextDecl,
227 bool isInstance = true,
228 bool isVariadic = false,
229 bool isPropertyAccessor = false,
230 bool isImplicitlyDeclared = false,
231 bool isDefined = false,
232 ImplementationControl impControl = None,
233 bool HasRelatedResultType = false)
234 : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
235 DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
236 IsInstance(isInstance), IsVariadic(isVariadic),
237 IsPropertyAccessor(isPropertyAccessor),
238 IsDefined(isDefined), IsRedeclaration(0), HasRedeclaration(0),
239 DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
240 RelatedResultType(HasRelatedResultType),
241 SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0),
242 MethodDeclType(T), ResultTInfo(ResultTInfo),
243 ParamsAndSelLocs(0), NumParams(0),
244 DeclEndLoc(endLoc), Body(), SelfDecl(0), CmdDecl(0) {
245 setImplicit(isImplicitlyDeclared);
248 /// \brief A definition will return its interface declaration.
249 /// An interface declaration will return its definition.
250 /// Otherwise it will return itself.
251 virtual ObjCMethodDecl *getNextRedeclaration();
254 static ObjCMethodDecl *Create(ASTContext &C,
255 SourceLocation beginLoc,
256 SourceLocation endLoc,
259 TypeSourceInfo *ResultTInfo,
260 DeclContext *contextDecl,
261 bool isInstance = true,
262 bool isVariadic = false,
263 bool isPropertyAccessor = false,
264 bool isImplicitlyDeclared = false,
265 bool isDefined = false,
266 ImplementationControl impControl = None,
267 bool HasRelatedResultType = false);
269 static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
271 virtual ObjCMethodDecl *getCanonicalDecl();
272 const ObjCMethodDecl *getCanonicalDecl() const {
273 return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
276 ObjCDeclQualifier getObjCDeclQualifier() const {
277 return ObjCDeclQualifier(objcDeclQualifier);
279 void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
281 /// \brief Determine whether this method has a result type that is related
282 /// to the message receiver's type.
283 bool hasRelatedResultType() const { return RelatedResultType; }
285 /// \brief Note whether this method has a related result type.
286 void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; }
288 /// \brief True if this is a method redeclaration in the same interface.
289 bool isRedeclaration() const { return IsRedeclaration; }
290 void setAsRedeclaration(const ObjCMethodDecl *PrevMethod);
292 /// \brief Returns the location where the declarator ends. It will be
293 /// the location of ';' for a method declaration and the location of '{'
294 /// for a method definition.
295 SourceLocation getDeclaratorEndLoc() const { return DeclEndLoc; }
297 // Location information, modeled after the Stmt API.
298 SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); }
299 SourceLocation getLocEnd() const LLVM_READONLY;
300 virtual SourceRange getSourceRange() const LLVM_READONLY {
301 return SourceRange(getLocation(), getLocEnd());
304 SourceLocation getSelectorStartLoc() const {
306 return getLocStart();
307 return getSelectorLoc(0);
309 SourceLocation getSelectorLoc(unsigned Index) const {
310 assert(Index < getNumSelectorLocs() && "Index out of range!");
311 if (hasStandardSelLocs())
312 return getStandardSelectorLoc(Index, getSelector(),
313 getSelLocsKind() == SelLoc_StandardWithSpace,
314 llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
317 return getStoredSelLocs()[Index];
320 void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
322 unsigned getNumSelectorLocs() const {
325 Selector Sel = getSelector();
326 if (Sel.isUnarySelector())
328 return Sel.getNumArgs();
331 ObjCInterfaceDecl *getClassInterface();
332 const ObjCInterfaceDecl *getClassInterface() const {
333 return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
336 Selector getSelector() const { return getDeclName().getObjCSelector(); }
338 QualType getResultType() const { return MethodDeclType; }
339 void setResultType(QualType T) { MethodDeclType = T; }
341 /// \brief Determine the type of an expression that sends a message to this
343 QualType getSendResultType() const {
344 return getResultType().getNonLValueExprType(getASTContext());
347 TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; }
348 void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; }
350 // Iterator access to formal parameters.
351 unsigned param_size() const { return NumParams; }
352 typedef const ParmVarDecl *const *param_const_iterator;
353 typedef ParmVarDecl *const *param_iterator;
354 param_const_iterator param_begin() const { return getParams(); }
355 param_const_iterator param_end() const { return getParams() + NumParams; }
356 param_iterator param_begin() { return getParams(); }
357 param_iterator param_end() { return getParams() + NumParams; }
358 // This method returns and of the parameters which are part of the selector
359 // name mangling requirements.
360 param_const_iterator sel_param_end() const {
361 return param_begin() + getSelector().getNumArgs();
364 /// \brief Sets the method's parameters and selector source locations.
365 /// If the method is implicit (not coming from source) \p SelLocs is
367 void setMethodParams(ASTContext &C,
368 ArrayRef<ParmVarDecl*> Params,
369 ArrayRef<SourceLocation> SelLocs =
370 ArrayRef<SourceLocation>());
372 // Iterator access to parameter types.
373 typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
374 typedef llvm::mapped_iterator<param_const_iterator, deref_fun>
377 arg_type_iterator arg_type_begin() const {
378 return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
380 arg_type_iterator arg_type_end() const {
381 return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType));
384 /// createImplicitParams - Used to lazily create the self and cmd
385 /// implict parameters. This must be called prior to using getSelfDecl()
386 /// or getCmdDecl(). The call is ignored if the implicit paramters
387 /// have already been created.
388 void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
390 ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
391 void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; }
392 ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
393 void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; }
395 /// Determines the family of this method.
396 ObjCMethodFamily getMethodFamily() const;
398 bool isInstanceMethod() const { return IsInstance; }
399 void setInstanceMethod(bool isInst) { IsInstance = isInst; }
400 bool isVariadic() const { return IsVariadic; }
401 void setVariadic(bool isVar) { IsVariadic = isVar; }
403 bool isClassMethod() const { return !IsInstance; }
405 bool isPropertyAccessor() const { return IsPropertyAccessor; }
406 void setPropertyAccessor(bool isAccessor) { IsPropertyAccessor = isAccessor; }
408 bool isDefined() const { return IsDefined; }
409 void setDefined(bool isDefined) { IsDefined = isDefined; }
411 /// \brief Whether this method overrides any other in the class hierarchy.
413 /// A method is said to override any method in the class's
414 /// base classes, its protocols, or its categories' protocols, that has
415 /// the same selector and is of the same kind (class or instance).
416 /// A method in an implementation is not considered as overriding the same
417 /// method in the interface or its categories.
418 bool isOverriding() const { return IsOverriding; }
419 void setOverriding(bool isOverriding) { IsOverriding = isOverriding; }
421 /// \brief Return overridden methods for the given \p Method.
423 /// An ObjC method is considered to override any method in the class's
424 /// base classes (and base's categories), its protocols, or its categories'
425 /// protocols, that has
426 /// the same selector and is of the same kind (class or instance).
427 /// A method in an implementation is not considered as overriding the same
428 /// method in the interface or its categories.
429 void getOverriddenMethods(
430 SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const;
432 /// \brief Returns the property associated with this method's selector.
434 /// Note that even if this particular method is not marked as a property
435 /// accessor, it is still possible for it to match a property declared in a
436 /// superclass. Pass \c false if you only want to check the current class.
437 const ObjCPropertyDecl *findPropertyDecl(bool CheckOverrides = true) const;
439 // Related to protocols declared in \@protocol
440 void setDeclImplementation(ImplementationControl ic) {
441 DeclImplementation = ic;
443 ImplementationControl getImplementationControl() const {
444 return ImplementationControl(DeclImplementation);
447 /// \brief Determine whether this method has a body.
448 virtual bool hasBody() const { return Body; }
450 /// \brief Retrieve the body of this method, if it has one.
451 virtual Stmt *getBody() const;
453 void setLazyBody(uint64_t Offset) { Body = Offset; }
455 CompoundStmt *getCompoundBody() { return (CompoundStmt*)getBody(); }
456 void setBody(Stmt *B) { Body = B; }
458 /// \brief Returns whether this specific method is a definition.
459 bool isThisDeclarationADefinition() const { return Body; }
461 // Implement isa/cast/dyncast/etc.
462 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
463 static bool classofKind(Kind K) { return K == ObjCMethod; }
464 static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
465 return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
467 static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) {
468 return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC));
471 friend class ASTDeclReader;
472 friend class ASTDeclWriter;
475 /// ObjCContainerDecl - Represents a container for method declarations.
476 /// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
477 /// ObjCProtocolDecl, and ObjCImplDecl.
479 class ObjCContainerDecl : public NamedDecl, public DeclContext {
480 virtual void anchor();
482 SourceLocation AtStart;
484 // These two locations in the range mark the end of the method container.
485 // The first points to the '@' token, and the second to the 'end' token.
489 ObjCContainerDecl(Kind DK, DeclContext *DC,
490 IdentifierInfo *Id, SourceLocation nameLoc,
491 SourceLocation atStartLoc)
492 : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {}
494 // Iterator access to properties.
495 typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
496 prop_iterator prop_begin() const {
497 return prop_iterator(decls_begin());
499 prop_iterator prop_end() const {
500 return prop_iterator(decls_end());
503 // Iterator access to instance/class methods.
504 typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
505 method_iterator meth_begin() const {
506 return method_iterator(decls_begin());
508 method_iterator meth_end() const {
509 return method_iterator(decls_end());
512 typedef filtered_decl_iterator<ObjCMethodDecl,
513 &ObjCMethodDecl::isInstanceMethod>
515 instmeth_iterator instmeth_begin() const {
516 return instmeth_iterator(decls_begin());
518 instmeth_iterator instmeth_end() const {
519 return instmeth_iterator(decls_end());
522 typedef filtered_decl_iterator<ObjCMethodDecl,
523 &ObjCMethodDecl::isClassMethod>
525 classmeth_iterator classmeth_begin() const {
526 return classmeth_iterator(decls_begin());
528 classmeth_iterator classmeth_end() const {
529 return classmeth_iterator(decls_end());
532 // Get the local instance/class method declared in this interface.
533 ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const;
534 ObjCMethodDecl *getInstanceMethod(Selector Sel) const {
535 return getMethod(Sel, true/*isInstance*/);
537 ObjCMethodDecl *getClassMethod(Selector Sel) const {
538 return getMethod(Sel, false/*isInstance*/);
540 ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
542 ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
544 typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap;
546 /// This routine collects list of properties to be implemented in the class.
547 /// This includes, class's and its conforming protocols' properties.
548 /// Note, the superclass's properties are not included in the list.
549 virtual void collectPropertiesToImplement(PropertyMap &PM) const {}
551 SourceLocation getAtStartLoc() const { return AtStart; }
552 void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; }
554 // Marks the end of the container.
555 SourceRange getAtEndRange() const {
558 void setAtEndRange(SourceRange atEnd) {
562 virtual SourceRange getSourceRange() const LLVM_READONLY {
563 return SourceRange(AtStart, getAtEndRange().getEnd());
566 // Implement isa/cast/dyncast/etc.
567 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
568 static bool classofKind(Kind K) {
569 return K >= firstObjCContainer &&
570 K <= lastObjCContainer;
573 static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
574 return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
576 static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) {
577 return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC));
581 /// \brief Represents an ObjC class declaration.
586 /// // MostPrimitive declares no super class (not particularly useful).
587 /// \@interface MostPrimitive
588 /// // no instance variables or methods.
591 /// // NSResponder inherits from NSObject & implements NSCoding (a protocol).
592 /// \@interface NSResponder : NSObject \<NSCoding>
593 /// { // instance variables are represented by ObjCIvarDecl.
594 /// id nextResponder; // nextResponder instance variable.
596 /// - (NSResponder *)nextResponder; // return a pointer to NSResponder.
597 /// - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
598 /// \@end // to an NSEvent.
601 /// Unlike C/C++, forward class declarations are accomplished with \@class.
602 /// Unlike C/C++, \@class allows for a list of classes to be forward declared.
603 /// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
604 /// typically inherit from NSObject (an exception is NSProxy).
606 class ObjCInterfaceDecl : public ObjCContainerDecl
607 , public Redeclarable<ObjCInterfaceDecl> {
608 virtual void anchor();
610 /// TypeForDecl - This indicates the Type object that represents this
611 /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
612 mutable const Type *TypeForDecl;
613 friend class ASTContext;
615 struct DefinitionData {
616 /// \brief The definition of this class, for quick access from any
618 ObjCInterfaceDecl *Definition;
620 /// Class's super class.
621 ObjCInterfaceDecl *SuperClass;
623 /// Protocols referenced in the \@interface declaration
624 ObjCProtocolList ReferencedProtocols;
626 /// Protocols reference in both the \@interface and class extensions.
627 ObjCList<ObjCProtocolDecl> AllReferencedProtocols;
629 /// \brief List of categories and class extensions defined for this class.
631 /// Categories are stored as a linked list in the AST, since the categories
632 /// and class extensions come long after the initial interface declaration,
633 /// and we avoid dynamically-resized arrays in the AST wherever possible.
634 ObjCCategoryDecl *CategoryList;
636 /// IvarList - List of all ivars defined by this class; including class
637 /// extensions and implementation. This list is built lazily.
638 ObjCIvarDecl *IvarList;
640 /// \brief Indicates that the contents of this Objective-C class will be
641 /// completed by the external AST source when required.
642 mutable bool ExternallyCompleted : 1;
644 /// \brief The location of the superclass, if any.
645 SourceLocation SuperClassLoc;
647 /// \brief The location of the last location in this declaration, before
648 /// the properties/methods. For example, this will be the '>', '}', or
650 SourceLocation EndLoc;
652 DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(),
653 ExternallyCompleted() { }
656 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
657 SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
660 void LoadExternalDefinition() const;
662 /// \brief Contains a pointer to the data associated with this class,
663 /// which will be NULL if this class has not yet been defined.
664 DefinitionData *Data;
666 DefinitionData &data() const {
667 assert(Data != 0 && "Declaration has no definition!");
671 /// \brief Allocate the definition data for this class.
672 void allocateDefinitionData();
674 typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
675 virtual ObjCInterfaceDecl *getNextRedeclaration() {
676 return RedeclLink.getNext();
678 virtual ObjCInterfaceDecl *getPreviousDeclImpl() {
679 return getPreviousDecl();
681 virtual ObjCInterfaceDecl *getMostRecentDeclImpl() {
682 return getMostRecentDecl();
686 static ObjCInterfaceDecl *Create(const ASTContext &C, DeclContext *DC,
687 SourceLocation atLoc,
689 ObjCInterfaceDecl *PrevDecl,
690 SourceLocation ClassLoc = SourceLocation(),
691 bool isInternal = false);
693 static ObjCInterfaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
695 virtual SourceRange getSourceRange() const LLVM_READONLY {
696 if (isThisDeclarationADefinition())
697 return ObjCContainerDecl::getSourceRange();
699 return SourceRange(getAtStartLoc(), getLocation());
702 /// \brief Indicate that this Objective-C class is complete, but that
703 /// the external AST source will be responsible for filling in its contents
704 /// when a complete class is required.
705 void setExternallyCompleted();
707 const ObjCProtocolList &getReferencedProtocols() const {
708 assert(hasDefinition() && "Caller did not check for forward reference!");
709 if (data().ExternallyCompleted)
710 LoadExternalDefinition();
712 return data().ReferencedProtocols;
715 ObjCImplementationDecl *getImplementation() const;
716 void setImplementation(ObjCImplementationDecl *ImplD);
718 ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
720 // Get the local instance/class method declared in a category.
721 ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const;
722 ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const;
723 ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const {
724 return isInstance ? getInstanceMethod(Sel)
725 : getClassMethod(Sel);
728 typedef ObjCProtocolList::iterator protocol_iterator;
730 protocol_iterator protocol_begin() const {
731 // FIXME: Should make sure no callers ever do this.
732 if (!hasDefinition())
733 return protocol_iterator();
735 if (data().ExternallyCompleted)
736 LoadExternalDefinition();
738 return data().ReferencedProtocols.begin();
740 protocol_iterator protocol_end() const {
741 // FIXME: Should make sure no callers ever do this.
742 if (!hasDefinition())
743 return protocol_iterator();
745 if (data().ExternallyCompleted)
746 LoadExternalDefinition();
748 return data().ReferencedProtocols.end();
751 typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
753 protocol_loc_iterator protocol_loc_begin() const {
754 // FIXME: Should make sure no callers ever do this.
755 if (!hasDefinition())
756 return protocol_loc_iterator();
758 if (data().ExternallyCompleted)
759 LoadExternalDefinition();
761 return data().ReferencedProtocols.loc_begin();
764 protocol_loc_iterator protocol_loc_end() const {
765 // FIXME: Should make sure no callers ever do this.
766 if (!hasDefinition())
767 return protocol_loc_iterator();
769 if (data().ExternallyCompleted)
770 LoadExternalDefinition();
772 return data().ReferencedProtocols.loc_end();
775 typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator;
777 all_protocol_iterator all_referenced_protocol_begin() const {
778 // FIXME: Should make sure no callers ever do this.
779 if (!hasDefinition())
780 return all_protocol_iterator();
782 if (data().ExternallyCompleted)
783 LoadExternalDefinition();
785 return data().AllReferencedProtocols.empty()
787 : data().AllReferencedProtocols.begin();
789 all_protocol_iterator all_referenced_protocol_end() const {
790 // FIXME: Should make sure no callers ever do this.
791 if (!hasDefinition())
792 return all_protocol_iterator();
794 if (data().ExternallyCompleted)
795 LoadExternalDefinition();
797 return data().AllReferencedProtocols.empty()
799 : data().AllReferencedProtocols.end();
802 typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
804 ivar_iterator ivar_begin() const {
805 if (const ObjCInterfaceDecl *Def = getDefinition())
806 return ivar_iterator(Def->decls_begin());
808 // FIXME: Should make sure no callers ever do this.
809 return ivar_iterator();
811 ivar_iterator ivar_end() const {
812 if (const ObjCInterfaceDecl *Def = getDefinition())
813 return ivar_iterator(Def->decls_end());
815 // FIXME: Should make sure no callers ever do this.
816 return ivar_iterator();
819 unsigned ivar_size() const {
820 return std::distance(ivar_begin(), ivar_end());
823 bool ivar_empty() const { return ivar_begin() == ivar_end(); }
825 ObjCIvarDecl *all_declared_ivar_begin();
826 const ObjCIvarDecl *all_declared_ivar_begin() const {
827 // Even though this modifies IvarList, it's conceptually const:
828 // the ivar chain is essentially a cached property of ObjCInterfaceDecl.
829 return const_cast<ObjCInterfaceDecl *>(this)->all_declared_ivar_begin();
831 void setIvarList(ObjCIvarDecl *ivar) { data().IvarList = ivar; }
833 /// setProtocolList - Set the list of protocols that this interface
835 void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
836 const SourceLocation *Locs, ASTContext &C) {
837 data().ReferencedProtocols.set(List, Num, Locs, C);
840 /// mergeClassExtensionProtocolList - Merge class extension's protocol list
841 /// into the protocol list for this class.
842 void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List,
846 /// \brief Determine whether this particular declaration of this class is
847 /// actually also a definition.
848 bool isThisDeclarationADefinition() const {
849 return Data && Data->Definition == this;
852 /// \brief Determine whether this class has been defined.
853 bool hasDefinition() const { return Data; }
855 /// \brief Retrieve the definition of this class, or NULL if this class
856 /// has been forward-declared (with \@class) but not yet defined (with
858 ObjCInterfaceDecl *getDefinition() {
859 return hasDefinition()? Data->Definition : 0;
862 /// \brief Retrieve the definition of this class, or NULL if this class
863 /// has been forward-declared (with \@class) but not yet defined (with
865 const ObjCInterfaceDecl *getDefinition() const {
866 return hasDefinition()? Data->Definition : 0;
869 /// \brief Starts the definition of this Objective-C class, taking it from
870 /// a forward declaration (\@class) to a definition (\@interface).
871 void startDefinition();
873 ObjCInterfaceDecl *getSuperClass() const {
874 // FIXME: Should make sure no callers ever do this.
875 if (!hasDefinition())
878 if (data().ExternallyCompleted)
879 LoadExternalDefinition();
881 return data().SuperClass;
884 void setSuperClass(ObjCInterfaceDecl * superCls) {
886 (superCls && superCls->hasDefinition()) ? superCls->getDefinition()
890 ObjCCategoryDecl* getCategoryList() const {
891 // FIXME: Should make sure no callers ever do this.
892 if (!hasDefinition())
895 if (data().ExternallyCompleted)
896 LoadExternalDefinition();
898 return data().CategoryList;
901 void setCategoryList(ObjCCategoryDecl *category) {
902 data().CategoryList = category;
905 ObjCCategoryDecl* getFirstClassExtension() const;
908 *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
910 virtual void collectPropertiesToImplement(PropertyMap &PM) const;
912 /// isSuperClassOf - Return true if this class is the specified class or is a
913 /// super class of the specified interface class.
914 bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
915 // If RHS is derived from LHS it is OK; else it is not OK.
917 if (declaresSameEntity(this, I))
920 I = I->getSuperClass();
925 /// isArcWeakrefUnavailable - Checks for a class or one of its super classes
926 /// to be incompatible with __weak references. Returns true if it is.
927 bool isArcWeakrefUnavailable() const {
928 const ObjCInterfaceDecl *Class = this;
930 if (Class->hasAttr<ArcWeakrefUnavailableAttr>())
932 Class = Class->getSuperClass();
937 /// isObjCRequiresPropertyDefs - Checks that a class or one of its super
938 /// classes must not be auto-synthesized. Returns class decl. if it must not
939 /// be; 0, otherwise.
940 const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const {
941 const ObjCInterfaceDecl *Class = this;
943 if (Class->hasAttr<ObjCRequiresPropertyDefsAttr>())
945 Class = Class->getSuperClass();
950 ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
951 ObjCInterfaceDecl *&ClassDeclared);
952 ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
953 ObjCInterfaceDecl *ClassDeclared;
954 return lookupInstanceVariable(IVarName, ClassDeclared);
957 // Lookup a method. First, we search locally. If a method isn't
958 // found, we search referenced protocols and class categories.
959 ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
960 bool shallowCategoryLookup= false) const;
961 ObjCMethodDecl *lookupInstanceMethod(Selector Sel,
962 bool shallowCategoryLookup = false) const {
963 return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup);
965 ObjCMethodDecl *lookupClassMethod(Selector Sel,
966 bool shallowCategoryLookup = false) const {
967 return lookupMethod(Sel, false/*isInstance*/, shallowCategoryLookup);
969 ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
971 /// \brief Lookup a method in the classes implementation hierarchy.
972 ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel,
973 bool Instance=true) const;
975 ObjCMethodDecl *lookupPrivateClassMethod(const Selector &Sel) {
976 return lookupPrivateMethod(Sel, false);
979 SourceLocation getEndOfDefinitionLoc() const {
980 if (!hasDefinition())
981 return getLocation();
983 return data().EndLoc;
986 void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; }
988 void setSuperClassLoc(SourceLocation Loc) { data().SuperClassLoc = Loc; }
989 SourceLocation getSuperClassLoc() const { return data().SuperClassLoc; }
991 /// isImplicitInterfaceDecl - check that this is an implicitly declared
992 /// ObjCInterfaceDecl node. This is for legacy objective-c \@implementation
993 /// declaration without an \@interface declaration.
994 bool isImplicitInterfaceDecl() const {
995 return hasDefinition() ? Data->Definition->isImplicit() : isImplicit();
998 /// ClassImplementsProtocol - Checks that 'lProto' protocol
999 /// has been implemented in IDecl class, its super class or categories (if
1000 /// lookupCategory is true).
1001 bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
1002 bool lookupCategory,
1003 bool RHSIsQualifiedID = false);
1005 typedef redeclarable_base::redecl_iterator redecl_iterator;
1006 using redeclarable_base::redecls_begin;
1007 using redeclarable_base::redecls_end;
1008 using redeclarable_base::getPreviousDecl;
1009 using redeclarable_base::getMostRecentDecl;
1011 /// Retrieves the canonical declaration of this Objective-C class.
1012 ObjCInterfaceDecl *getCanonicalDecl() {
1013 return getFirstDeclaration();
1015 const ObjCInterfaceDecl *getCanonicalDecl() const {
1016 return getFirstDeclaration();
1019 // Low-level accessor
1020 const Type *getTypeForDecl() const { return TypeForDecl; }
1021 void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }
1023 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1024 static bool classofKind(Kind K) { return K == ObjCInterface; }
1026 friend class ASTReader;
1027 friend class ASTDeclReader;
1028 friend class ASTDeclWriter;
1031 /// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
1032 /// instance variables are identical to C. The only exception is Objective-C
1033 /// supports C++ style access control. For example:
1035 /// \@interface IvarExample : NSObject
1037 /// id defaultToProtected;
1039 /// id canBePublic; // same as C++.
1041 /// id canBeProtected; // same as C++.
1043 /// id canBePackage; // framework visibility (not available in C++).
1046 class ObjCIvarDecl : public FieldDecl {
1047 virtual void anchor();
1050 enum AccessControl {
1051 None, Private, Protected, Public, Package
1055 ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
1056 SourceLocation IdLoc, IdentifierInfo *Id,
1057 QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
1059 : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
1060 /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
1061 NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {}
1064 static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
1065 SourceLocation StartLoc, SourceLocation IdLoc,
1066 IdentifierInfo *Id, QualType T,
1067 TypeSourceInfo *TInfo,
1068 AccessControl ac, Expr *BW = NULL,
1069 bool synthesized=false);
1071 static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1073 /// \brief Return the class interface that this ivar is logically contained
1074 /// in; this is either the interface where the ivar was declared, or the
1075 /// interface the ivar is conceptually a part of in the case of synthesized
1077 const ObjCInterfaceDecl *getContainingInterface() const;
1079 ObjCIvarDecl *getNextIvar() { return NextIvar; }
1080 const ObjCIvarDecl *getNextIvar() const { return NextIvar; }
1081 void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
1083 void setAccessControl(AccessControl ac) { DeclAccess = ac; }
1085 AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
1087 AccessControl getCanonicalAccessControl() const {
1088 return DeclAccess == None ? Protected : AccessControl(DeclAccess);
1091 void setSynthesize(bool synth) { Synthesized = synth; }
1092 bool getSynthesize() const { return Synthesized; }
1094 // Implement isa/cast/dyncast/etc.
1095 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1096 static bool classofKind(Kind K) { return K == ObjCIvar; }
1098 /// NextIvar - Next Ivar in the list of ivars declared in class; class's
1099 /// extensions and class's implementation
1100 ObjCIvarDecl *NextIvar;
1102 // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
1103 unsigned DeclAccess : 3;
1104 unsigned Synthesized : 1;
1108 /// \brief Represents a field declaration created by an \@defs(...).
1109 class ObjCAtDefsFieldDecl : public FieldDecl {
1110 virtual void anchor();
1111 ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
1112 SourceLocation IdLoc, IdentifierInfo *Id,
1113 QualType T, Expr *BW)
1114 : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
1115 /*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ?
1116 BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
1119 static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
1120 SourceLocation StartLoc,
1121 SourceLocation IdLoc, IdentifierInfo *Id,
1122 QualType T, Expr *BW);
1124 static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1126 // Implement isa/cast/dyncast/etc.
1127 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1128 static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
1131 /// \brief Represents an Objective-C protocol declaration.
1133 /// Objective-C protocols declare a pure abstract type (i.e., no instance
1134 /// variables are permitted). Protocols originally drew inspiration from
1135 /// C++ pure virtual functions (a C++ feature with nice semantics and lousy
1136 /// syntax:-). Here is an example:
1139 /// \@protocol NSDraggingInfo <refproto1, refproto2>
1140 /// - (NSWindow *)draggingDestinationWindow;
1141 /// - (NSImage *)draggedImage;
1145 /// This says that NSDraggingInfo requires two methods and requires everything
1146 /// that the two "referenced protocols" 'refproto1' and 'refproto2' require as
1150 /// \@interface ImplementsNSDraggingInfo : NSObject \<NSDraggingInfo>
1154 /// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
1155 /// protocols are in distinct namespaces. For example, Cocoa defines both
1156 /// an NSObject protocol and class (which isn't allowed in Java). As a result,
1157 /// protocols are referenced using angle brackets as follows:
1159 /// id \<NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
1161 class ObjCProtocolDecl : public ObjCContainerDecl,
1162 public Redeclarable<ObjCProtocolDecl> {
1163 virtual void anchor();
1165 struct DefinitionData {
1166 // \brief The declaration that defines this protocol.
1167 ObjCProtocolDecl *Definition;
1169 /// \brief Referenced protocols
1170 ObjCProtocolList ReferencedProtocols;
1173 DefinitionData *Data;
1175 DefinitionData &data() const {
1176 assert(Data && "Objective-C protocol has no definition!");
1180 ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
1181 SourceLocation nameLoc, SourceLocation atStartLoc,
1182 ObjCProtocolDecl *PrevDecl);
1184 void allocateDefinitionData();
1186 typedef Redeclarable<ObjCProtocolDecl> redeclarable_base;
1187 virtual ObjCProtocolDecl *getNextRedeclaration() {
1188 return RedeclLink.getNext();
1190 virtual ObjCProtocolDecl *getPreviousDeclImpl() {
1191 return getPreviousDecl();
1193 virtual ObjCProtocolDecl *getMostRecentDeclImpl() {
1194 return getMostRecentDecl();
1198 static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
1200 SourceLocation nameLoc,
1201 SourceLocation atStartLoc,
1202 ObjCProtocolDecl *PrevDecl);
1204 static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1206 const ObjCProtocolList &getReferencedProtocols() const {
1207 assert(hasDefinition() && "No definition available!");
1208 return data().ReferencedProtocols;
1210 typedef ObjCProtocolList::iterator protocol_iterator;
1211 protocol_iterator protocol_begin() const {
1212 if (!hasDefinition())
1213 return protocol_iterator();
1215 return data().ReferencedProtocols.begin();
1217 protocol_iterator protocol_end() const {
1218 if (!hasDefinition())
1219 return protocol_iterator();
1221 return data().ReferencedProtocols.end();
1223 typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
1224 protocol_loc_iterator protocol_loc_begin() const {
1225 if (!hasDefinition())
1226 return protocol_loc_iterator();
1228 return data().ReferencedProtocols.loc_begin();
1230 protocol_loc_iterator protocol_loc_end() const {
1231 if (!hasDefinition())
1232 return protocol_loc_iterator();
1234 return data().ReferencedProtocols.loc_end();
1236 unsigned protocol_size() const {
1237 if (!hasDefinition())
1240 return data().ReferencedProtocols.size();
1243 /// setProtocolList - Set the list of protocols that this interface
1245 void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
1246 const SourceLocation *Locs, ASTContext &C) {
1247 assert(Data && "Protocol is not defined");
1248 data().ReferencedProtocols.set(List, Num, Locs, C);
1251 ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName);
1253 // Lookup a method. First, we search locally. If a method isn't
1254 // found, we search referenced protocols and class categories.
1255 ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const;
1256 ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
1257 return lookupMethod(Sel, true/*isInstance*/);
1259 ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
1260 return lookupMethod(Sel, false/*isInstance*/);
1263 /// \brief Determine whether this protocol has a definition.
1264 bool hasDefinition() const { return Data != 0; }
1266 /// \brief Retrieve the definition of this protocol, if any.
1267 ObjCProtocolDecl *getDefinition() {
1268 return Data? Data->Definition : 0;
1271 /// \brief Retrieve the definition of this protocol, if any.
1272 const ObjCProtocolDecl *getDefinition() const {
1273 return Data? Data->Definition : 0;
1276 /// \brief Determine whether this particular declaration is also the
1278 bool isThisDeclarationADefinition() const {
1279 return getDefinition() == this;
1282 /// \brief Starts the definition of this Objective-C protocol.
1283 void startDefinition();
1285 virtual SourceRange getSourceRange() const LLVM_READONLY {
1286 if (isThisDeclarationADefinition())
1287 return ObjCContainerDecl::getSourceRange();
1289 return SourceRange(getAtStartLoc(), getLocation());
1292 typedef redeclarable_base::redecl_iterator redecl_iterator;
1293 using redeclarable_base::redecls_begin;
1294 using redeclarable_base::redecls_end;
1295 using redeclarable_base::getPreviousDecl;
1296 using redeclarable_base::getMostRecentDecl;
1298 /// Retrieves the canonical declaration of this Objective-C protocol.
1299 ObjCProtocolDecl *getCanonicalDecl() {
1300 return getFirstDeclaration();
1302 const ObjCProtocolDecl *getCanonicalDecl() const {
1303 return getFirstDeclaration();
1306 virtual void collectPropertiesToImplement(PropertyMap &PM) const;
1308 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1309 static bool classofKind(Kind K) { return K == ObjCProtocol; }
1311 friend class ASTReader;
1312 friend class ASTDeclReader;
1313 friend class ASTDeclWriter;
1316 /// ObjCCategoryDecl - Represents a category declaration. A category allows
1317 /// you to add methods to an existing class (without subclassing or modifying
1318 /// the original class interface or implementation:-). Categories don't allow
1319 /// you to add instance data. The following example adds "myMethod" to all
1320 /// NSView's within a process:
1322 /// \@interface NSView (MyViewMethods)
1326 /// Categories also allow you to split the implementation of a class across
1327 /// several files (a feature more naturally supported in C++).
1329 /// Categories were originally inspired by dynamic languages such as Common
1330 /// Lisp and Smalltalk. More traditional class-based languages (C++, Java)
1331 /// don't support this level of dynamism, which is both powerful and dangerous.
1333 class ObjCCategoryDecl : public ObjCContainerDecl {
1334 virtual void anchor();
1336 /// Interface belonging to this category
1337 ObjCInterfaceDecl *ClassInterface;
1339 /// referenced protocols in this category.
1340 ObjCProtocolList ReferencedProtocols;
1342 /// Next category belonging to this class.
1343 /// FIXME: this should not be a singly-linked list. Move storage elsewhere.
1344 ObjCCategoryDecl *NextClassCategory;
1346 /// \brief The location of the category name in this declaration.
1347 SourceLocation CategoryNameLoc;
1349 /// class extension may have private ivars.
1350 SourceLocation IvarLBraceLoc;
1351 SourceLocation IvarRBraceLoc;
1353 ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
1354 SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
1355 IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
1356 SourceLocation IvarLBraceLoc=SourceLocation(),
1357 SourceLocation IvarRBraceLoc=SourceLocation())
1358 : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
1359 ClassInterface(IDecl), NextClassCategory(0),
1360 CategoryNameLoc(CategoryNameLoc),
1361 IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
1365 static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
1366 SourceLocation AtLoc,
1367 SourceLocation ClassNameLoc,
1368 SourceLocation CategoryNameLoc,
1370 ObjCInterfaceDecl *IDecl,
1371 SourceLocation IvarLBraceLoc=SourceLocation(),
1372 SourceLocation IvarRBraceLoc=SourceLocation());
1373 static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1375 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
1376 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
1378 ObjCCategoryImplDecl *getImplementation() const;
1379 void setImplementation(ObjCCategoryImplDecl *ImplD);
1381 /// setProtocolList - Set the list of protocols that this interface
1383 void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
1384 const SourceLocation *Locs, ASTContext &C) {
1385 ReferencedProtocols.set(List, Num, Locs, C);
1388 const ObjCProtocolList &getReferencedProtocols() const {
1389 return ReferencedProtocols;
1392 typedef ObjCProtocolList::iterator protocol_iterator;
1393 protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
1394 protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
1395 unsigned protocol_size() const { return ReferencedProtocols.size(); }
1396 typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
1397 protocol_loc_iterator protocol_loc_begin() const {
1398 return ReferencedProtocols.loc_begin();
1400 protocol_loc_iterator protocol_loc_end() const {
1401 return ReferencedProtocols.loc_end();
1404 ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
1406 bool IsClassExtension() const { return getIdentifier() == 0; }
1407 const ObjCCategoryDecl *getNextClassExtension() const;
1409 typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
1410 ivar_iterator ivar_begin() const {
1411 return ivar_iterator(decls_begin());
1413 ivar_iterator ivar_end() const {
1414 return ivar_iterator(decls_end());
1416 unsigned ivar_size() const {
1417 return std::distance(ivar_begin(), ivar_end());
1419 bool ivar_empty() const {
1420 return ivar_begin() == ivar_end();
1423 SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
1424 void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; }
1426 void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
1427 SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
1428 void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
1429 SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
1431 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1432 static bool classofKind(Kind K) { return K == ObjCCategory; }
1434 friend class ASTDeclReader;
1435 friend class ASTDeclWriter;
1438 class ObjCImplDecl : public ObjCContainerDecl {
1439 virtual void anchor();
1441 /// Class interface for this class/category implementation
1442 ObjCInterfaceDecl *ClassInterface;
1445 ObjCImplDecl(Kind DK, DeclContext *DC,
1446 ObjCInterfaceDecl *classInterface,
1447 SourceLocation nameLoc, SourceLocation atStartLoc)
1448 : ObjCContainerDecl(DK, DC,
1449 classInterface? classInterface->getIdentifier() : 0,
1450 nameLoc, atStartLoc),
1451 ClassInterface(classInterface) {}
1454 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
1455 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
1456 void setClassInterface(ObjCInterfaceDecl *IFace);
1458 void addInstanceMethod(ObjCMethodDecl *method) {
1459 // FIXME: Context should be set correctly before we get here.
1460 method->setLexicalDeclContext(this);
1463 void addClassMethod(ObjCMethodDecl *method) {
1464 // FIXME: Context should be set correctly before we get here.
1465 method->setLexicalDeclContext(this);
1469 void addPropertyImplementation(ObjCPropertyImplDecl *property);
1471 ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
1472 ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
1474 // Iterator access to properties.
1475 typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
1476 propimpl_iterator propimpl_begin() const {
1477 return propimpl_iterator(decls_begin());
1479 propimpl_iterator propimpl_end() const {
1480 return propimpl_iterator(decls_end());
1483 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1484 static bool classofKind(Kind K) {
1485 return K >= firstObjCImpl && K <= lastObjCImpl;
1489 /// ObjCCategoryImplDecl - An object of this class encapsulates a category
1490 /// \@implementation declaration. If a category class has declaration of a
1491 /// property, its implementation must be specified in the category's
1492 /// \@implementation declaration. Example:
1493 /// \@interface I \@end
1494 /// \@interface I(CATEGORY)
1495 /// \@property int p1, d1;
1497 /// \@implementation I(CATEGORY)
1498 /// \@dynamic p1,d1;
1501 /// ObjCCategoryImplDecl
1502 class ObjCCategoryImplDecl : public ObjCImplDecl {
1503 virtual void anchor();
1508 // Category name location
1509 SourceLocation CategoryNameLoc;
1511 ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id,
1512 ObjCInterfaceDecl *classInterface,
1513 SourceLocation nameLoc, SourceLocation atStartLoc,
1514 SourceLocation CategoryNameLoc)
1515 : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc),
1516 Id(Id), CategoryNameLoc(CategoryNameLoc) {}
1518 static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
1520 ObjCInterfaceDecl *classInterface,
1521 SourceLocation nameLoc,
1522 SourceLocation atStartLoc,
1523 SourceLocation CategoryNameLoc);
1524 static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1526 /// getIdentifier - Get the identifier that names the category
1527 /// interface associated with this implementation.
1528 /// FIXME: This is a bad API, we are overriding the NamedDecl::getIdentifier()
1529 /// to mean something different. For example:
1530 /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
1531 /// returns the class interface name, whereas
1532 /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
1533 /// returns the category name.
1534 IdentifierInfo *getIdentifier() const {
1537 void setIdentifier(IdentifierInfo *II) { Id = II; }
1539 ObjCCategoryDecl *getCategoryDecl() const;
1541 SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
1543 /// getName - Get the name of identifier for the class interface associated
1544 /// with this implementation as a StringRef.
1546 // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
1547 // something different.
1548 StringRef getName() const {
1549 return Id ? Id->getNameStart() : "";
1552 /// @brief Get the name of the class associated with this interface.
1554 // FIXME: Deprecated, move clients to getName().
1555 std::string getNameAsString() const {
1559 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1560 static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
1562 friend class ASTDeclReader;
1563 friend class ASTDeclWriter;
1566 raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID);
1568 /// ObjCImplementationDecl - Represents a class definition - this is where
1569 /// method definitions are specified. For example:
1572 /// \@implementation MyClass
1573 /// - (void)myMethod { /* do something */ }
1577 /// Typically, instance variables are specified in the class interface,
1578 /// *not* in the implementation. Nevertheless (for legacy reasons), we
1579 /// allow instance variables to be specified in the implementation. When
1580 /// specified, they need to be *identical* to the interface.
1582 class ObjCImplementationDecl : public ObjCImplDecl {
1583 virtual void anchor();
1584 /// Implementation Class's super class.
1585 ObjCInterfaceDecl *SuperClass;
1586 /// \@implementation may have private ivars.
1587 SourceLocation IvarLBraceLoc;
1588 SourceLocation IvarRBraceLoc;
1590 /// Support for ivar initialization.
1591 /// IvarInitializers - The arguments used to initialize the ivars
1592 CXXCtorInitializer **IvarInitializers;
1593 unsigned NumIvarInitializers;
1595 /// Do the ivars of this class require initialization other than
1596 /// zero-initialization?
1597 bool HasNonZeroConstructors : 1;
1599 /// Do the ivars of this class require non-trivial destruction?
1600 bool HasDestructors : 1;
1602 ObjCImplementationDecl(DeclContext *DC,
1603 ObjCInterfaceDecl *classInterface,
1604 ObjCInterfaceDecl *superDecl,
1605 SourceLocation nameLoc, SourceLocation atStartLoc,
1606 SourceLocation IvarLBraceLoc=SourceLocation(),
1607 SourceLocation IvarRBraceLoc=SourceLocation())
1608 : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
1609 SuperClass(superDecl), IvarLBraceLoc(IvarLBraceLoc),
1610 IvarRBraceLoc(IvarRBraceLoc),
1611 IvarInitializers(0), NumIvarInitializers(0),
1612 HasNonZeroConstructors(false), HasDestructors(false) {}
1614 static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
1615 ObjCInterfaceDecl *classInterface,
1616 ObjCInterfaceDecl *superDecl,
1617 SourceLocation nameLoc,
1618 SourceLocation atStartLoc,
1619 SourceLocation IvarLBraceLoc=SourceLocation(),
1620 SourceLocation IvarRBraceLoc=SourceLocation());
1622 static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1624 /// init_iterator - Iterates through the ivar initializer list.
1625 typedef CXXCtorInitializer **init_iterator;
1627 /// init_const_iterator - Iterates through the ivar initializer list.
1628 typedef CXXCtorInitializer * const * init_const_iterator;
1630 /// init_begin() - Retrieve an iterator to the first initializer.
1631 init_iterator init_begin() { return IvarInitializers; }
1632 /// begin() - Retrieve an iterator to the first initializer.
1633 init_const_iterator init_begin() const { return IvarInitializers; }
1635 /// init_end() - Retrieve an iterator past the last initializer.
1636 init_iterator init_end() {
1637 return IvarInitializers + NumIvarInitializers;
1639 /// end() - Retrieve an iterator past the last initializer.
1640 init_const_iterator init_end() const {
1641 return IvarInitializers + NumIvarInitializers;
1643 /// getNumArgs - Number of ivars which must be initialized.
1644 unsigned getNumIvarInitializers() const {
1645 return NumIvarInitializers;
1648 void setNumIvarInitializers(unsigned numNumIvarInitializers) {
1649 NumIvarInitializers = numNumIvarInitializers;
1652 void setIvarInitializers(ASTContext &C,
1653 CXXCtorInitializer ** initializers,
1654 unsigned numInitializers);
1656 /// Do any of the ivars of this class (not counting its base classes)
1657 /// require construction other than zero-initialization?
1658 bool hasNonZeroConstructors() const { return HasNonZeroConstructors; }
1659 void setHasNonZeroConstructors(bool val) { HasNonZeroConstructors = val; }
1661 /// Do any of the ivars of this class (not counting its base classes)
1662 /// require non-trivial destruction?
1663 bool hasDestructors() const { return HasDestructors; }
1664 void setHasDestructors(bool val) { HasDestructors = val; }
1666 /// getIdentifier - Get the identifier that names the class
1667 /// interface associated with this implementation.
1668 IdentifierInfo *getIdentifier() const {
1669 return getClassInterface()->getIdentifier();
1672 /// getName - Get the name of identifier for the class interface associated
1673 /// with this implementation as a StringRef.
1675 // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
1676 // something different.
1677 StringRef getName() const {
1678 assert(getIdentifier() && "Name is not a simple identifier");
1679 return getIdentifier()->getName();
1682 /// @brief Get the name of the class associated with this interface.
1684 // FIXME: Move to StringRef API.
1685 std::string getNameAsString() const {
1689 const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
1690 ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
1692 void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
1694 void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
1695 SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
1696 void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
1697 SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
1699 typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
1700 ivar_iterator ivar_begin() const {
1701 return ivar_iterator(decls_begin());
1703 ivar_iterator ivar_end() const {
1704 return ivar_iterator(decls_end());
1706 unsigned ivar_size() const {
1707 return std::distance(ivar_begin(), ivar_end());
1709 bool ivar_empty() const {
1710 return ivar_begin() == ivar_end();
1713 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1714 static bool classofKind(Kind K) { return K == ObjCImplementation; }
1716 friend class ASTDeclReader;
1717 friend class ASTDeclWriter;
1720 raw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID);
1722 /// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
1723 /// declared as \@compatibility_alias alias class.
1724 class ObjCCompatibleAliasDecl : public NamedDecl {
1725 virtual void anchor();
1726 /// Class that this is an alias of.
1727 ObjCInterfaceDecl *AliasedClass;
1729 ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
1730 ObjCInterfaceDecl* aliasedClass)
1731 : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {}
1733 static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC,
1734 SourceLocation L, IdentifierInfo *Id,
1735 ObjCInterfaceDecl* aliasedClass);
1737 static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C,
1740 const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
1741 ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
1742 void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
1744 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1745 static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
1749 /// \brief Represents one property declaration in an Objective-C interface.
1753 /// \@property (assign, readwrite) int MyProperty;
1755 class ObjCPropertyDecl : public NamedDecl {
1756 virtual void anchor();
1758 enum PropertyAttributeKind {
1759 OBJC_PR_noattr = 0x00,
1760 OBJC_PR_readonly = 0x01,
1761 OBJC_PR_getter = 0x02,
1762 OBJC_PR_assign = 0x04,
1763 OBJC_PR_readwrite = 0x08,
1764 OBJC_PR_retain = 0x10,
1765 OBJC_PR_copy = 0x20,
1766 OBJC_PR_nonatomic = 0x40,
1767 OBJC_PR_setter = 0x80,
1768 OBJC_PR_atomic = 0x100,
1769 OBJC_PR_weak = 0x200,
1770 OBJC_PR_strong = 0x400,
1771 OBJC_PR_unsafe_unretained = 0x800
1772 // Adding a property should change NumPropertyAttrsBits
1776 /// \brief Number of bits fitting all the property attributes.
1777 NumPropertyAttrsBits = 12
1780 enum SetterKind { Assign, Retain, Copy, Weak };
1781 enum PropertyControl { None, Required, Optional };
1783 SourceLocation AtLoc; // location of \@property
1784 SourceLocation LParenLoc; // location of '(' starting attribute list or null.
1785 TypeSourceInfo *DeclType;
1786 unsigned PropertyAttributes : NumPropertyAttrsBits;
1787 unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
1788 // \@required/\@optional
1789 unsigned PropertyImplementation : 2;
1791 Selector GetterName; // getter name of NULL if no getter
1792 Selector SetterName; // setter name of NULL if no setter
1794 ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
1795 ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
1796 ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property
1798 ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
1799 SourceLocation AtLocation, SourceLocation LParenLocation,
1801 : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
1802 LParenLoc(LParenLocation), DeclType(T),
1803 PropertyAttributes(OBJC_PR_noattr),
1804 PropertyAttributesAsWritten(OBJC_PR_noattr),
1805 PropertyImplementation(None),
1806 GetterName(Selector()),
1807 SetterName(Selector()),
1808 GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {}
1810 static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
1812 IdentifierInfo *Id, SourceLocation AtLocation,
1813 SourceLocation LParenLocation,
1815 PropertyControl propControl = None);
1817 static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1819 SourceLocation getAtLoc() const { return AtLoc; }
1820 void setAtLoc(SourceLocation L) { AtLoc = L; }
1822 SourceLocation getLParenLoc() const { return LParenLoc; }
1823 void setLParenLoc(SourceLocation L) { LParenLoc = L; }
1825 TypeSourceInfo *getTypeSourceInfo() const { return DeclType; }
1826 QualType getType() const { return DeclType->getType(); }
1827 void setType(TypeSourceInfo *T) { DeclType = T; }
1829 PropertyAttributeKind getPropertyAttributes() const {
1830 return PropertyAttributeKind(PropertyAttributes);
1832 void setPropertyAttributes(PropertyAttributeKind PRVal) {
1833 PropertyAttributes |= PRVal;
1836 PropertyAttributeKind getPropertyAttributesAsWritten() const {
1837 return PropertyAttributeKind(PropertyAttributesAsWritten);
1840 bool hasWrittenStorageAttribute() const {
1841 return PropertyAttributesAsWritten & (OBJC_PR_assign | OBJC_PR_copy |
1842 OBJC_PR_unsafe_unretained | OBJC_PR_retain | OBJC_PR_strong |
1846 void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
1847 PropertyAttributesAsWritten = PRVal;
1850 void makeitReadWriteAttribute(void) {
1851 PropertyAttributes &= ~OBJC_PR_readonly;
1852 PropertyAttributes |= OBJC_PR_readwrite;
1855 // Helper methods for accessing attributes.
1857 /// isReadOnly - Return true iff the property has a setter.
1858 bool isReadOnly() const {
1859 return (PropertyAttributes & OBJC_PR_readonly);
1862 /// isAtomic - Return true if the property is atomic.
1863 bool isAtomic() const {
1864 return (PropertyAttributes & OBJC_PR_atomic);
1867 /// isRetaining - Return true if the property retains its value.
1868 bool isRetaining() const {
1869 return (PropertyAttributes &
1870 (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy));
1873 /// getSetterKind - Return the method used for doing assignment in
1874 /// the property setter. This is only valid if the property has been
1875 /// defined to have a setter.
1876 SetterKind getSetterKind() const {
1877 if (PropertyAttributes & OBJC_PR_strong)
1878 return getType()->isBlockPointerType() ? Copy : Retain;
1879 if (PropertyAttributes & OBJC_PR_retain)
1881 if (PropertyAttributes & OBJC_PR_copy)
1883 if (PropertyAttributes & OBJC_PR_weak)
1888 Selector getGetterName() const { return GetterName; }
1889 void setGetterName(Selector Sel) { GetterName = Sel; }
1891 Selector getSetterName() const { return SetterName; }
1892 void setSetterName(Selector Sel) { SetterName = Sel; }
1894 ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
1895 void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
1897 ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
1898 void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
1900 // Related to \@optional/\@required declared in \@protocol
1901 void setPropertyImplementation(PropertyControl pc) {
1902 PropertyImplementation = pc;
1904 PropertyControl getPropertyImplementation() const {
1905 return PropertyControl(PropertyImplementation);
1908 void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
1909 PropertyIvarDecl = Ivar;
1911 ObjCIvarDecl *getPropertyIvarDecl() const {
1912 return PropertyIvarDecl;
1915 virtual SourceRange getSourceRange() const LLVM_READONLY {
1916 return SourceRange(AtLoc, getLocation());
1919 /// Get the default name of the synthesized ivar.
1920 IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const;
1922 /// Lookup a property by name in the specified DeclContext.
1923 static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
1924 IdentifierInfo *propertyID);
1926 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1927 static bool classofKind(Kind K) { return K == ObjCProperty; }
1930 /// ObjCPropertyImplDecl - Represents implementation declaration of a property
1931 /// in a class or category implementation block. For example:
1932 /// \@synthesize prop1 = ivar1;
1934 class ObjCPropertyImplDecl : public Decl {
1941 SourceLocation AtLoc; // location of \@synthesize or \@dynamic
1943 /// \brief For \@synthesize, the location of the ivar, if it was written in
1944 /// the source code.
1947 /// \@synthesize int a = b
1949 SourceLocation IvarLoc;
1951 /// Property declaration being implemented
1952 ObjCPropertyDecl *PropertyDecl;
1954 /// Null for \@dynamic. Required for \@synthesize.
1955 ObjCIvarDecl *PropertyIvarDecl;
1957 /// Null for \@dynamic. Non-null if property must be copy-constructed in
1959 Expr *GetterCXXConstructor;
1961 /// Null for \@dynamic. Non-null if property has assignment operator to call
1962 /// in Setter synthesis.
1963 Expr *SetterCXXAssignment;
1965 ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
1966 ObjCPropertyDecl *property,
1968 ObjCIvarDecl *ivarDecl,
1969 SourceLocation ivarLoc)
1970 : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
1971 IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl),
1972 GetterCXXConstructor(0), SetterCXXAssignment(0) {
1973 assert (PK == Dynamic || PropertyIvarDecl);
1977 static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC,
1978 SourceLocation atLoc, SourceLocation L,
1979 ObjCPropertyDecl *property,
1981 ObjCIvarDecl *ivarDecl,
1982 SourceLocation ivarLoc);
1984 static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1986 virtual SourceRange getSourceRange() const LLVM_READONLY;
1988 SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
1989 void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
1991 ObjCPropertyDecl *getPropertyDecl() const {
1992 return PropertyDecl;
1994 void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; }
1996 Kind getPropertyImplementation() const {
1997 return PropertyIvarDecl ? Synthesize : Dynamic;
2000 ObjCIvarDecl *getPropertyIvarDecl() const {
2001 return PropertyIvarDecl;
2003 SourceLocation getPropertyIvarDeclLoc() const { return IvarLoc; }
2005 void setPropertyIvarDecl(ObjCIvarDecl *Ivar,
2006 SourceLocation IvarLoc) {
2007 PropertyIvarDecl = Ivar;
2008 this->IvarLoc = IvarLoc;
2011 /// \brief For \@synthesize, returns true if an ivar name was explicitly
2015 /// \@synthesize int a = b; // true
2016 /// \@synthesize int a; // false
2018 bool isIvarNameSpecified() const {
2019 return IvarLoc.isValid() && IvarLoc != getLocation();
2022 Expr *getGetterCXXConstructor() const {
2023 return GetterCXXConstructor;
2025 void setGetterCXXConstructor(Expr *getterCXXConstructor) {
2026 GetterCXXConstructor = getterCXXConstructor;
2029 Expr *getSetterCXXAssignment() const {
2030 return SetterCXXAssignment;
2032 void setSetterCXXAssignment(Expr *setterCXXAssignment) {
2033 SetterCXXAssignment = setterCXXAssignment;
2036 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2037 static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
2039 friend class ASTDeclReader;
2042 } // end namespace clang