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 void operator=(const ObjCListBase &); // DO NOT IMPLEMENT
37 ObjCListBase(const ObjCListBase&); // DO NOT IMPLEMENT
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 // Synthesized declaration method for a property setter/getter
127 unsigned IsSynthesized : 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 // Result type of this method.
154 QualType MethodDeclType;
156 // Type source information for the result type.
157 TypeSourceInfo *ResultTInfo;
159 /// \brief Array of ParmVarDecls for the formal parameters of this method
160 /// and optionally followed by selector locations.
161 void *ParamsAndSelLocs;
164 /// List of attributes for this method declaration.
165 SourceLocation EndLoc; // the location of the ';' or '}'.
167 // The following are only used for method definitions, null otherwise.
168 // FIXME: space savings opportunity, consider a sub-class.
171 /// SelfDecl - Decl for the implicit self parameter. This is lazily
172 /// constructed by createImplicitParams.
173 ImplicitParamDecl *SelfDecl;
174 /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily
175 /// constructed by createImplicitParams.
176 ImplicitParamDecl *CmdDecl;
178 SelectorLocationsKind getSelLocsKind() const {
179 return (SelectorLocationsKind)SelLocsKind;
181 bool hasStandardSelLocs() const {
182 return getSelLocsKind() != SelLoc_NonStandard;
185 /// \brief Get a pointer to the stored selector identifiers locations array.
186 /// No locations will be stored if HasStandardSelLocs is true.
187 SourceLocation *getStoredSelLocs() {
188 return reinterpret_cast<SourceLocation*>(getParams() + NumParams);
190 const SourceLocation *getStoredSelLocs() const {
191 return reinterpret_cast<const SourceLocation*>(getParams() + NumParams);
194 /// \brief Get a pointer to the stored selector identifiers locations array.
195 /// No locations will be stored if HasStandardSelLocs is true.
196 ParmVarDecl **getParams() {
197 return reinterpret_cast<ParmVarDecl **>(ParamsAndSelLocs);
199 const ParmVarDecl *const *getParams() const {
200 return reinterpret_cast<const ParmVarDecl *const *>(ParamsAndSelLocs);
203 /// \brief Get the number of stored selector identifiers locations.
204 /// No locations will be stored if HasStandardSelLocs is true.
205 unsigned getNumStoredSelLocs() const {
206 if (hasStandardSelLocs())
208 return getNumSelectorLocs();
211 void setParamsAndSelLocs(ASTContext &C,
212 ArrayRef<ParmVarDecl*> Params,
213 ArrayRef<SourceLocation> SelLocs);
215 ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
216 Selector SelInfo, QualType T,
217 TypeSourceInfo *ResultTInfo,
218 DeclContext *contextDecl,
219 bool isInstance = true,
220 bool isVariadic = false,
221 bool isSynthesized = false,
222 bool isImplicitlyDeclared = false,
223 bool isDefined = false,
224 ImplementationControl impControl = None,
225 bool HasRelatedResultType = false)
226 : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
227 DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
228 IsInstance(isInstance), IsVariadic(isVariadic),
229 IsSynthesized(isSynthesized),
230 IsDefined(isDefined), IsRedeclaration(0), HasRedeclaration(0),
231 DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
232 RelatedResultType(HasRelatedResultType),
233 SelLocsKind(SelLoc_StandardNoSpace),
234 MethodDeclType(T), ResultTInfo(ResultTInfo),
235 ParamsAndSelLocs(0), NumParams(0),
236 EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {
237 setImplicit(isImplicitlyDeclared);
240 /// \brief A definition will return its interface declaration.
241 /// An interface declaration will return its definition.
242 /// Otherwise it will return itself.
243 virtual ObjCMethodDecl *getNextRedeclaration();
246 static ObjCMethodDecl *Create(ASTContext &C,
247 SourceLocation beginLoc,
248 SourceLocation endLoc,
251 TypeSourceInfo *ResultTInfo,
252 DeclContext *contextDecl,
253 bool isInstance = true,
254 bool isVariadic = false,
255 bool isSynthesized = false,
256 bool isImplicitlyDeclared = false,
257 bool isDefined = false,
258 ImplementationControl impControl = None,
259 bool HasRelatedResultType = false);
261 static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
263 virtual ObjCMethodDecl *getCanonicalDecl();
264 const ObjCMethodDecl *getCanonicalDecl() const {
265 return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
268 ObjCDeclQualifier getObjCDeclQualifier() const {
269 return ObjCDeclQualifier(objcDeclQualifier);
271 void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
273 /// \brief Determine whether this method has a result type that is related
274 /// to the message receiver's type.
275 bool hasRelatedResultType() const { return RelatedResultType; }
277 /// \brief Note whether this method has a related result type.
278 void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; }
280 /// \brief True if this is a method redeclaration in the same interface.
281 bool isRedeclaration() const { return IsRedeclaration; }
282 void setAsRedeclaration(const ObjCMethodDecl *PrevMethod);
284 // Location information, modeled after the Stmt API.
285 SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); }
286 SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
287 void setEndLoc(SourceLocation Loc) { EndLoc = Loc; }
288 virtual SourceRange getSourceRange() const LLVM_READONLY {
289 return SourceRange(getLocation(), EndLoc);
292 SourceLocation getSelectorStartLoc() const {
294 return getLocStart();
295 return getSelectorLoc(0);
297 SourceLocation getSelectorLoc(unsigned Index) const {
298 assert(Index < getNumSelectorLocs() && "Index out of range!");
299 if (hasStandardSelLocs())
300 return getStandardSelectorLoc(Index, getSelector(),
301 getSelLocsKind() == SelLoc_StandardWithSpace,
302 llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
305 return getStoredSelLocs()[Index];
308 void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
310 unsigned getNumSelectorLocs() const {
313 Selector Sel = getSelector();
314 if (Sel.isUnarySelector())
316 return Sel.getNumArgs();
319 ObjCInterfaceDecl *getClassInterface();
320 const ObjCInterfaceDecl *getClassInterface() const {
321 return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
324 Selector getSelector() const { return getDeclName().getObjCSelector(); }
326 QualType getResultType() const { return MethodDeclType; }
327 void setResultType(QualType T) { MethodDeclType = T; }
329 /// \brief Determine the type of an expression that sends a message to this
331 QualType getSendResultType() const {
332 return getResultType().getNonLValueExprType(getASTContext());
335 TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; }
336 void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; }
338 // Iterator access to formal parameters.
339 unsigned param_size() const { return NumParams; }
340 typedef const ParmVarDecl *const *param_const_iterator;
341 typedef ParmVarDecl *const *param_iterator;
342 param_const_iterator param_begin() const { return getParams(); }
343 param_const_iterator param_end() const { return getParams() + NumParams; }
344 param_iterator param_begin() { return getParams(); }
345 param_iterator param_end() { return getParams() + NumParams; }
346 // This method returns and of the parameters which are part of the selector
347 // name mangling requirements.
348 param_const_iterator sel_param_end() const {
349 return param_begin() + getSelector().getNumArgs();
352 /// \brief Sets the method's parameters and selector source locations.
353 /// If the method is implicit (not coming from source) \arg SelLocs is
355 void setMethodParams(ASTContext &C,
356 ArrayRef<ParmVarDecl*> Params,
357 ArrayRef<SourceLocation> SelLocs =
358 ArrayRef<SourceLocation>());
360 // Iterator access to parameter types.
361 typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
362 typedef llvm::mapped_iterator<param_const_iterator, deref_fun>
365 arg_type_iterator arg_type_begin() const {
366 return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
368 arg_type_iterator arg_type_end() const {
369 return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType));
372 /// createImplicitParams - Used to lazily create the self and cmd
373 /// implict parameters. This must be called prior to using getSelfDecl()
374 /// or getCmdDecl(). The call is ignored if the implicit paramters
375 /// have already been created.
376 void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
378 ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
379 void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; }
380 ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
381 void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; }
383 /// Determines the family of this method.
384 ObjCMethodFamily getMethodFamily() const;
386 bool isInstanceMethod() const { return IsInstance; }
387 void setInstanceMethod(bool isInst) { IsInstance = isInst; }
388 bool isVariadic() const { return IsVariadic; }
389 void setVariadic(bool isVar) { IsVariadic = isVar; }
391 bool isClassMethod() const { return !IsInstance; }
393 bool isSynthesized() const { return IsSynthesized; }
394 void setSynthesized(bool isSynth) { IsSynthesized = isSynth; }
396 bool isDefined() const { return IsDefined; }
397 void setDefined(bool isDefined) { IsDefined = isDefined; }
399 // Related to protocols declared in @protocol
400 void setDeclImplementation(ImplementationControl ic) {
401 DeclImplementation = ic;
403 ImplementationControl getImplementationControl() const {
404 return ImplementationControl(DeclImplementation);
407 virtual Stmt *getBody() const {
410 CompoundStmt *getCompoundBody() { return (CompoundStmt*)Body; }
411 void setBody(Stmt *B) { Body = B; }
413 /// \brief Returns whether this specific method is a definition.
414 bool isThisDeclarationADefinition() const { return Body; }
416 // Implement isa/cast/dyncast/etc.
417 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
418 static bool classof(const ObjCMethodDecl *D) { return true; }
419 static bool classofKind(Kind K) { return K == ObjCMethod; }
420 static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
421 return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
423 static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) {
424 return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC));
427 friend class ASTDeclReader;
428 friend class ASTDeclWriter;
431 /// ObjCContainerDecl - Represents a container for method declarations.
432 /// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
433 /// ObjCProtocolDecl, and ObjCImplDecl.
435 class ObjCContainerDecl : public NamedDecl, public DeclContext {
436 virtual void anchor();
438 SourceLocation AtStart;
440 // These two locations in the range mark the end of the method container.
441 // The first points to the '@' token, and the second to the 'end' token.
445 ObjCContainerDecl(Kind DK, DeclContext *DC,
446 IdentifierInfo *Id, SourceLocation nameLoc,
447 SourceLocation atStartLoc)
448 : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {}
450 // Iterator access to properties.
451 typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
452 prop_iterator prop_begin() const {
453 return prop_iterator(decls_begin());
455 prop_iterator prop_end() const {
456 return prop_iterator(decls_end());
459 // Iterator access to instance/class methods.
460 typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
461 method_iterator meth_begin() const {
462 return method_iterator(decls_begin());
464 method_iterator meth_end() const {
465 return method_iterator(decls_end());
468 typedef filtered_decl_iterator<ObjCMethodDecl,
469 &ObjCMethodDecl::isInstanceMethod>
471 instmeth_iterator instmeth_begin() const {
472 return instmeth_iterator(decls_begin());
474 instmeth_iterator instmeth_end() const {
475 return instmeth_iterator(decls_end());
478 typedef filtered_decl_iterator<ObjCMethodDecl,
479 &ObjCMethodDecl::isClassMethod>
481 classmeth_iterator classmeth_begin() const {
482 return classmeth_iterator(decls_begin());
484 classmeth_iterator classmeth_end() const {
485 return classmeth_iterator(decls_end());
488 // Get the local instance/class method declared in this interface.
489 ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const;
490 ObjCMethodDecl *getInstanceMethod(Selector Sel) const {
491 return getMethod(Sel, true/*isInstance*/);
493 ObjCMethodDecl *getClassMethod(Selector Sel) const {
494 return getMethod(Sel, false/*isInstance*/);
496 ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
498 ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
500 SourceLocation getAtStartLoc() const { return AtStart; }
501 void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; }
503 // Marks the end of the container.
504 SourceRange getAtEndRange() const {
507 void setAtEndRange(SourceRange atEnd) {
511 virtual SourceRange getSourceRange() const LLVM_READONLY {
512 return SourceRange(AtStart, getAtEndRange().getEnd());
515 // Implement isa/cast/dyncast/etc.
516 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
517 static bool classof(const ObjCContainerDecl *D) { return true; }
518 static bool classofKind(Kind K) {
519 return K >= firstObjCContainer &&
520 K <= lastObjCContainer;
523 static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
524 return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
526 static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) {
527 return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC));
531 /// ObjCInterfaceDecl - Represents an ObjC class declaration. For example:
533 /// // MostPrimitive declares no super class (not particularly useful).
534 /// @interface MostPrimitive
535 /// // no instance variables or methods.
538 /// // NSResponder inherits from NSObject & implements NSCoding (a protocol).
539 /// @interface NSResponder : NSObject <NSCoding>
540 /// { // instance variables are represented by ObjCIvarDecl.
541 /// id nextResponder; // nextResponder instance variable.
543 /// - (NSResponder *)nextResponder; // return a pointer to NSResponder.
544 /// - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
545 /// @end // to an NSEvent.
547 /// Unlike C/C++, forward class declarations are accomplished with @class.
548 /// Unlike C/C++, @class allows for a list of classes to be forward declared.
549 /// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
550 /// typically inherit from NSObject (an exception is NSProxy).
552 class ObjCInterfaceDecl : public ObjCContainerDecl
553 , public Redeclarable<ObjCInterfaceDecl> {
554 virtual void anchor();
556 /// TypeForDecl - This indicates the Type object that represents this
557 /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
558 mutable const Type *TypeForDecl;
559 friend class ASTContext;
561 struct DefinitionData {
562 /// \brief The definition of this class, for quick access from any
564 ObjCInterfaceDecl *Definition;
566 /// Class's super class.
567 ObjCInterfaceDecl *SuperClass;
569 /// Protocols referenced in the @interface declaration
570 ObjCProtocolList ReferencedProtocols;
572 /// Protocols reference in both the @interface and class extensions.
573 ObjCList<ObjCProtocolDecl> AllReferencedProtocols;
575 /// \brief List of categories and class extensions defined for this class.
577 /// Categories are stored as a linked list in the AST, since the categories
578 /// and class extensions come long after the initial interface declaration,
579 /// and we avoid dynamically-resized arrays in the AST wherever possible.
580 ObjCCategoryDecl *CategoryList;
582 /// IvarList - List of all ivars defined by this class; including class
583 /// extensions and implementation. This list is built lazily.
584 ObjCIvarDecl *IvarList;
586 /// \brief Indicates that the contents of this Objective-C class will be
587 /// completed by the external AST source when required.
588 mutable bool ExternallyCompleted : 1;
590 /// \brief The location of the superclass, if any.
591 SourceLocation SuperClassLoc;
593 /// \brief The location of the last location in this declaration, before
594 /// the properties/methods. For example, this will be the '>', '}', or
596 SourceLocation EndLoc;
598 DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(),
599 ExternallyCompleted() { }
602 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
603 SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
606 void LoadExternalDefinition() const;
608 /// \brief Contains a pointer to the data associated with this class,
609 /// which will be NULL if this class has not yet been defined.
610 DefinitionData *Data;
612 DefinitionData &data() const {
613 assert(Data != 0 && "Declaration has no definition!");
617 /// \brief Allocate the definition data for this class.
618 void allocateDefinitionData();
620 typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
621 virtual ObjCInterfaceDecl *getNextRedeclaration() {
622 return RedeclLink.getNext();
624 virtual ObjCInterfaceDecl *getPreviousDeclImpl() {
625 return getPreviousDecl();
627 virtual ObjCInterfaceDecl *getMostRecentDeclImpl() {
628 return getMostRecentDecl();
632 static ObjCInterfaceDecl *Create(const ASTContext &C, DeclContext *DC,
633 SourceLocation atLoc,
635 ObjCInterfaceDecl *PrevDecl,
636 SourceLocation ClassLoc = SourceLocation(),
637 bool isInternal = false);
639 static ObjCInterfaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
641 virtual SourceRange getSourceRange() const LLVM_READONLY {
642 if (isThisDeclarationADefinition())
643 return ObjCContainerDecl::getSourceRange();
645 return SourceRange(getAtStartLoc(), getLocation());
648 /// \brief Indicate that this Objective-C class is complete, but that
649 /// the external AST source will be responsible for filling in its contents
650 /// when a complete class is required.
651 void setExternallyCompleted();
653 const ObjCProtocolList &getReferencedProtocols() const {
654 assert(hasDefinition() && "Caller did not check for forward reference!");
655 if (data().ExternallyCompleted)
656 LoadExternalDefinition();
658 return data().ReferencedProtocols;
661 ObjCImplementationDecl *getImplementation() const;
662 void setImplementation(ObjCImplementationDecl *ImplD);
664 ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
666 // Get the local instance/class method declared in a category.
667 ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const;
668 ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const;
669 ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const {
670 return isInstance ? getInstanceMethod(Sel)
671 : getClassMethod(Sel);
674 typedef ObjCProtocolList::iterator protocol_iterator;
676 protocol_iterator protocol_begin() const {
677 // FIXME: Should make sure no callers ever do this.
678 if (!hasDefinition())
679 return protocol_iterator();
681 if (data().ExternallyCompleted)
682 LoadExternalDefinition();
684 return data().ReferencedProtocols.begin();
686 protocol_iterator protocol_end() const {
687 // FIXME: Should make sure no callers ever do this.
688 if (!hasDefinition())
689 return protocol_iterator();
691 if (data().ExternallyCompleted)
692 LoadExternalDefinition();
694 return data().ReferencedProtocols.end();
697 typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
699 protocol_loc_iterator protocol_loc_begin() const {
700 // FIXME: Should make sure no callers ever do this.
701 if (!hasDefinition())
702 return protocol_loc_iterator();
704 if (data().ExternallyCompleted)
705 LoadExternalDefinition();
707 return data().ReferencedProtocols.loc_begin();
710 protocol_loc_iterator protocol_loc_end() const {
711 // FIXME: Should make sure no callers ever do this.
712 if (!hasDefinition())
713 return protocol_loc_iterator();
715 if (data().ExternallyCompleted)
716 LoadExternalDefinition();
718 return data().ReferencedProtocols.loc_end();
721 typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator;
723 all_protocol_iterator all_referenced_protocol_begin() const {
724 // FIXME: Should make sure no callers ever do this.
725 if (!hasDefinition())
726 return all_protocol_iterator();
728 if (data().ExternallyCompleted)
729 LoadExternalDefinition();
731 return data().AllReferencedProtocols.empty()
733 : data().AllReferencedProtocols.begin();
735 all_protocol_iterator all_referenced_protocol_end() const {
736 // FIXME: Should make sure no callers ever do this.
737 if (!hasDefinition())
738 return all_protocol_iterator();
740 if (data().ExternallyCompleted)
741 LoadExternalDefinition();
743 return data().AllReferencedProtocols.empty()
745 : data().AllReferencedProtocols.end();
748 typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
750 ivar_iterator ivar_begin() const {
751 if (const ObjCInterfaceDecl *Def = getDefinition())
752 return ivar_iterator(Def->decls_begin());
754 // FIXME: Should make sure no callers ever do this.
755 return ivar_iterator();
757 ivar_iterator ivar_end() const {
758 if (const ObjCInterfaceDecl *Def = getDefinition())
759 return ivar_iterator(Def->decls_end());
761 // FIXME: Should make sure no callers ever do this.
762 return ivar_iterator();
765 unsigned ivar_size() const {
766 return std::distance(ivar_begin(), ivar_end());
769 bool ivar_empty() const { return ivar_begin() == ivar_end(); }
771 ObjCIvarDecl *all_declared_ivar_begin();
772 const ObjCIvarDecl *all_declared_ivar_begin() const {
773 // Even though this modifies IvarList, it's conceptually const:
774 // the ivar chain is essentially a cached property of ObjCInterfaceDecl.
775 return const_cast<ObjCInterfaceDecl *>(this)->all_declared_ivar_begin();
777 void setIvarList(ObjCIvarDecl *ivar) { data().IvarList = ivar; }
779 /// setProtocolList - Set the list of protocols that this interface
781 void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
782 const SourceLocation *Locs, ASTContext &C) {
783 data().ReferencedProtocols.set(List, Num, Locs, C);
786 /// mergeClassExtensionProtocolList - Merge class extension's protocol list
787 /// into the protocol list for this class.
788 void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List,
792 /// \brief Determine whether this particular declaration of this class is
793 /// actually also a definition.
794 bool isThisDeclarationADefinition() const {
795 return Data && Data->Definition == this;
798 /// \brief Determine whether this class has been defined.
799 bool hasDefinition() const { return Data; }
801 /// \brief Retrieve the definition of this class, or NULL if this class
802 /// has been forward-declared (with @class) but not yet defined (with
804 ObjCInterfaceDecl *getDefinition() {
805 return hasDefinition()? Data->Definition : 0;
808 /// \brief Retrieve the definition of this class, or NULL if this class
809 /// has been forward-declared (with @class) but not yet defined (with
811 const ObjCInterfaceDecl *getDefinition() const {
812 return hasDefinition()? Data->Definition : 0;
815 /// \brief Starts the definition of this Objective-C class, taking it from
816 /// a forward declaration (@class) to a definition (@interface).
817 void startDefinition();
819 ObjCInterfaceDecl *getSuperClass() const {
820 // FIXME: Should make sure no callers ever do this.
821 if (!hasDefinition())
824 if (data().ExternallyCompleted)
825 LoadExternalDefinition();
827 return data().SuperClass;
830 void setSuperClass(ObjCInterfaceDecl * superCls) {
832 (superCls && superCls->hasDefinition()) ? superCls->getDefinition()
836 ObjCCategoryDecl* getCategoryList() const {
837 // FIXME: Should make sure no callers ever do this.
838 if (!hasDefinition())
841 if (data().ExternallyCompleted)
842 LoadExternalDefinition();
844 return data().CategoryList;
847 void setCategoryList(ObjCCategoryDecl *category) {
848 data().CategoryList = category;
851 ObjCCategoryDecl* getFirstClassExtension() const;
854 *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
856 /// isSuperClassOf - Return true if this class is the specified class or is a
857 /// super class of the specified interface class.
858 bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
859 // If RHS is derived from LHS it is OK; else it is not OK.
861 if (declaresSameEntity(this, I))
864 I = I->getSuperClass();
869 /// isArcWeakrefUnavailable - Checks for a class or one of its super classes
870 /// to be incompatible with __weak references. Returns true if it is.
871 bool isArcWeakrefUnavailable() const {
872 const ObjCInterfaceDecl *Class = this;
874 if (Class->hasAttr<ArcWeakrefUnavailableAttr>())
876 Class = Class->getSuperClass();
881 /// isObjCRequiresPropertyDefs - Checks that a class or one of its super
882 /// classes must not be auto-synthesized. Returns class decl. if it must not be;
884 const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const {
885 const ObjCInterfaceDecl *Class = this;
887 if (Class->hasAttr<ObjCRequiresPropertyDefsAttr>())
889 Class = Class->getSuperClass();
894 ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
895 ObjCInterfaceDecl *&ClassDeclared);
896 ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
897 ObjCInterfaceDecl *ClassDeclared;
898 return lookupInstanceVariable(IVarName, ClassDeclared);
901 // Lookup a method. First, we search locally. If a method isn't
902 // found, we search referenced protocols and class categories.
903 ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
904 bool shallowCategoryLookup= false) const;
905 ObjCMethodDecl *lookupInstanceMethod(Selector Sel,
906 bool shallowCategoryLookup = false) const {
907 return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup);
909 ObjCMethodDecl *lookupClassMethod(Selector Sel,
910 bool shallowCategoryLookup = false) const {
911 return lookupMethod(Sel, false/*isInstance*/, shallowCategoryLookup);
913 ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
915 // Lookup a method in the classes implementation hierarchy.
916 ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel, bool Instance=true);
918 SourceLocation getEndOfDefinitionLoc() const {
919 if (!hasDefinition())
920 return getLocation();
922 return data().EndLoc;
925 void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; }
927 void setSuperClassLoc(SourceLocation Loc) { data().SuperClassLoc = Loc; }
928 SourceLocation getSuperClassLoc() const { return data().SuperClassLoc; }
930 /// isImplicitInterfaceDecl - check that this is an implicitly declared
931 /// ObjCInterfaceDecl node. This is for legacy objective-c @implementation
932 /// declaration without an @interface declaration.
933 bool isImplicitInterfaceDecl() const {
934 return hasDefinition() ? Data->Definition->isImplicit() : isImplicit();
937 /// ClassImplementsProtocol - Checks that 'lProto' protocol
938 /// has been implemented in IDecl class, its super class or categories (if
939 /// lookupCategory is true).
940 bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
942 bool RHSIsQualifiedID = false);
944 typedef redeclarable_base::redecl_iterator redecl_iterator;
945 using redeclarable_base::redecls_begin;
946 using redeclarable_base::redecls_end;
947 using redeclarable_base::getPreviousDecl;
948 using redeclarable_base::getMostRecentDecl;
950 /// Retrieves the canonical declaration of this Objective-C class.
951 ObjCInterfaceDecl *getCanonicalDecl() {
952 return getFirstDeclaration();
954 const ObjCInterfaceDecl *getCanonicalDecl() const {
955 return getFirstDeclaration();
958 // Low-level accessor
959 const Type *getTypeForDecl() const { return TypeForDecl; }
960 void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }
962 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
963 static bool classof(const ObjCInterfaceDecl *D) { return true; }
964 static bool classofKind(Kind K) { return K == ObjCInterface; }
966 friend class ASTReader;
967 friend class ASTDeclReader;
968 friend class ASTDeclWriter;
971 /// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
972 /// instance variables are identical to C. The only exception is Objective-C
973 /// supports C++ style access control. For example:
975 /// @interface IvarExample : NSObject
977 /// id defaultToProtected;
979 /// id canBePublic; // same as C++.
981 /// id canBeProtected; // same as C++.
983 /// id canBePackage; // framework visibility (not available in C++).
986 class ObjCIvarDecl : public FieldDecl {
987 virtual void anchor();
991 None, Private, Protected, Public, Package
995 ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
996 SourceLocation IdLoc, IdentifierInfo *Id,
997 QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
999 : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
1000 /*Mutable=*/false, /*HasInit=*/false),
1001 NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {}
1004 static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
1005 SourceLocation StartLoc, SourceLocation IdLoc,
1006 IdentifierInfo *Id, QualType T,
1007 TypeSourceInfo *TInfo,
1008 AccessControl ac, Expr *BW = NULL,
1009 bool synthesized=false);
1011 static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1013 /// \brief Return the class interface that this ivar is logically contained
1014 /// in; this is either the interface where the ivar was declared, or the
1015 /// interface the ivar is conceptually a part of in the case of synthesized
1017 const ObjCInterfaceDecl *getContainingInterface() const;
1019 ObjCIvarDecl *getNextIvar() { return NextIvar; }
1020 const ObjCIvarDecl *getNextIvar() const { return NextIvar; }
1021 void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
1023 void setAccessControl(AccessControl ac) { DeclAccess = ac; }
1025 AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
1027 AccessControl getCanonicalAccessControl() const {
1028 return DeclAccess == None ? Protected : AccessControl(DeclAccess);
1031 void setSynthesize(bool synth) { Synthesized = synth; }
1032 bool getSynthesize() const { return Synthesized; }
1034 // Implement isa/cast/dyncast/etc.
1035 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1036 static bool classof(const ObjCIvarDecl *D) { return true; }
1037 static bool classofKind(Kind K) { return K == ObjCIvar; }
1039 /// NextIvar - Next Ivar in the list of ivars declared in class; class's
1040 /// extensions and class's implementation
1041 ObjCIvarDecl *NextIvar;
1043 // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
1044 unsigned DeclAccess : 3;
1045 unsigned Synthesized : 1;
1049 /// ObjCAtDefsFieldDecl - Represents a field declaration created by an
1051 class ObjCAtDefsFieldDecl : public FieldDecl {
1052 virtual void anchor();
1053 ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
1054 SourceLocation IdLoc, IdentifierInfo *Id,
1055 QualType T, Expr *BW)
1056 : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
1057 /*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ?
1058 BW, /*Mutable=*/false, /*HasInit=*/false) {}
1061 static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
1062 SourceLocation StartLoc,
1063 SourceLocation IdLoc, IdentifierInfo *Id,
1064 QualType T, Expr *BW);
1066 static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1068 // Implement isa/cast/dyncast/etc.
1069 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1070 static bool classof(const ObjCAtDefsFieldDecl *D) { return true; }
1071 static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
1074 /// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols
1075 /// declare a pure abstract type (i.e no instance variables are permitted).
1076 /// Protocols originally drew inspiration from C++ pure virtual functions (a C++
1077 /// feature with nice semantics and lousy syntax:-). Here is an example:
1079 /// @protocol NSDraggingInfo <refproto1, refproto2>
1080 /// - (NSWindow *)draggingDestinationWindow;
1081 /// - (NSImage *)draggedImage;
1084 /// This says that NSDraggingInfo requires two methods and requires everything
1085 /// that the two "referenced protocols" 'refproto1' and 'refproto2' require as
1088 /// @interface ImplementsNSDraggingInfo : NSObject <NSDraggingInfo>
1091 /// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
1092 /// protocols are in distinct namespaces. For example, Cocoa defines both
1093 /// an NSObject protocol and class (which isn't allowed in Java). As a result,
1094 /// protocols are referenced using angle brackets as follows:
1096 /// id <NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
1098 class ObjCProtocolDecl : public ObjCContainerDecl,
1099 public Redeclarable<ObjCProtocolDecl> {
1100 virtual void anchor();
1102 struct DefinitionData {
1103 // \brief The declaration that defines this protocol.
1104 ObjCProtocolDecl *Definition;
1106 /// \brief Referenced protocols
1107 ObjCProtocolList ReferencedProtocols;
1110 DefinitionData *Data;
1112 DefinitionData &data() const {
1113 assert(Data && "Objective-C protocol has no definition!");
1117 ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
1118 SourceLocation nameLoc, SourceLocation atStartLoc,
1119 ObjCProtocolDecl *PrevDecl);
1121 void allocateDefinitionData();
1123 typedef Redeclarable<ObjCProtocolDecl> redeclarable_base;
1124 virtual ObjCProtocolDecl *getNextRedeclaration() {
1125 return RedeclLink.getNext();
1127 virtual ObjCProtocolDecl *getPreviousDeclImpl() {
1128 return getPreviousDecl();
1130 virtual ObjCProtocolDecl *getMostRecentDeclImpl() {
1131 return getMostRecentDecl();
1135 static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
1137 SourceLocation nameLoc,
1138 SourceLocation atStartLoc,
1139 ObjCProtocolDecl *PrevDecl);
1141 static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1143 const ObjCProtocolList &getReferencedProtocols() const {
1144 assert(hasDefinition() && "No definition available!");
1145 return data().ReferencedProtocols;
1147 typedef ObjCProtocolList::iterator protocol_iterator;
1148 protocol_iterator protocol_begin() const {
1149 if (!hasDefinition())
1150 return protocol_iterator();
1152 return data().ReferencedProtocols.begin();
1154 protocol_iterator protocol_end() const {
1155 if (!hasDefinition())
1156 return protocol_iterator();
1158 return data().ReferencedProtocols.end();
1160 typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
1161 protocol_loc_iterator protocol_loc_begin() const {
1162 if (!hasDefinition())
1163 return protocol_loc_iterator();
1165 return data().ReferencedProtocols.loc_begin();
1167 protocol_loc_iterator protocol_loc_end() const {
1168 if (!hasDefinition())
1169 return protocol_loc_iterator();
1171 return data().ReferencedProtocols.loc_end();
1173 unsigned protocol_size() const {
1174 if (!hasDefinition())
1177 return data().ReferencedProtocols.size();
1180 /// setProtocolList - Set the list of protocols that this interface
1182 void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
1183 const SourceLocation *Locs, ASTContext &C) {
1184 assert(Data && "Protocol is not defined");
1185 data().ReferencedProtocols.set(List, Num, Locs, C);
1188 ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName);
1190 // Lookup a method. First, we search locally. If a method isn't
1191 // found, we search referenced protocols and class categories.
1192 ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const;
1193 ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
1194 return lookupMethod(Sel, true/*isInstance*/);
1196 ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
1197 return lookupMethod(Sel, false/*isInstance*/);
1200 /// \brief Determine whether this protocol has a definition.
1201 bool hasDefinition() const { return Data != 0; }
1203 /// \brief Retrieve the definition of this protocol, if any.
1204 ObjCProtocolDecl *getDefinition() {
1205 return Data? Data->Definition : 0;
1208 /// \brief Retrieve the definition of this protocol, if any.
1209 const ObjCProtocolDecl *getDefinition() const {
1210 return Data? Data->Definition : 0;
1213 /// \brief Determine whether this particular declaration is also the
1215 bool isThisDeclarationADefinition() const {
1216 return getDefinition() == this;
1219 /// \brief Starts the definition of this Objective-C protocol.
1220 void startDefinition();
1222 virtual SourceRange getSourceRange() const LLVM_READONLY {
1223 if (isThisDeclarationADefinition())
1224 return ObjCContainerDecl::getSourceRange();
1226 return SourceRange(getAtStartLoc(), getLocation());
1229 typedef redeclarable_base::redecl_iterator redecl_iterator;
1230 using redeclarable_base::redecls_begin;
1231 using redeclarable_base::redecls_end;
1232 using redeclarable_base::getPreviousDecl;
1233 using redeclarable_base::getMostRecentDecl;
1235 /// Retrieves the canonical declaration of this Objective-C protocol.
1236 ObjCProtocolDecl *getCanonicalDecl() {
1237 return getFirstDeclaration();
1239 const ObjCProtocolDecl *getCanonicalDecl() const {
1240 return getFirstDeclaration();
1243 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1244 static bool classof(const ObjCProtocolDecl *D) { return true; }
1245 static bool classofKind(Kind K) { return K == ObjCProtocol; }
1247 friend class ASTReader;
1248 friend class ASTDeclReader;
1249 friend class ASTDeclWriter;
1252 /// ObjCCategoryDecl - Represents a category declaration. A category allows
1253 /// you to add methods to an existing class (without subclassing or modifying
1254 /// the original class interface or implementation:-). Categories don't allow
1255 /// you to add instance data. The following example adds "myMethod" to all
1256 /// NSView's within a process:
1258 /// @interface NSView (MyViewMethods)
1262 /// Categories also allow you to split the implementation of a class across
1263 /// several files (a feature more naturally supported in C++).
1265 /// Categories were originally inspired by dynamic languages such as Common
1266 /// Lisp and Smalltalk. More traditional class-based languages (C++, Java)
1267 /// don't support this level of dynamism, which is both powerful and dangerous.
1269 class ObjCCategoryDecl : public ObjCContainerDecl {
1270 virtual void anchor();
1272 /// Interface belonging to this category
1273 ObjCInterfaceDecl *ClassInterface;
1275 /// referenced protocols in this category.
1276 ObjCProtocolList ReferencedProtocols;
1278 /// Next category belonging to this class.
1279 /// FIXME: this should not be a singly-linked list. Move storage elsewhere.
1280 ObjCCategoryDecl *NextClassCategory;
1282 /// true of class extension has at least one bitfield ivar.
1283 bool HasSynthBitfield : 1;
1285 /// \brief The location of the category name in this declaration.
1286 SourceLocation CategoryNameLoc;
1288 /// class extension may have private ivars.
1289 SourceLocation IvarLBraceLoc;
1290 SourceLocation IvarRBraceLoc;
1292 ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
1293 SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
1294 IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
1295 SourceLocation IvarLBraceLoc=SourceLocation(),
1296 SourceLocation IvarRBraceLoc=SourceLocation())
1297 : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
1298 ClassInterface(IDecl), NextClassCategory(0), HasSynthBitfield(false),
1299 CategoryNameLoc(CategoryNameLoc),
1300 IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
1304 static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
1305 SourceLocation AtLoc,
1306 SourceLocation ClassNameLoc,
1307 SourceLocation CategoryNameLoc,
1309 ObjCInterfaceDecl *IDecl,
1310 SourceLocation IvarLBraceLoc=SourceLocation(),
1311 SourceLocation IvarRBraceLoc=SourceLocation());
1312 static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1314 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
1315 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
1317 ObjCCategoryImplDecl *getImplementation() const;
1318 void setImplementation(ObjCCategoryImplDecl *ImplD);
1320 /// setProtocolList - Set the list of protocols that this interface
1322 void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
1323 const SourceLocation *Locs, ASTContext &C) {
1324 ReferencedProtocols.set(List, Num, Locs, C);
1327 const ObjCProtocolList &getReferencedProtocols() const {
1328 return ReferencedProtocols;
1331 typedef ObjCProtocolList::iterator protocol_iterator;
1332 protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
1333 protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
1334 unsigned protocol_size() const { return ReferencedProtocols.size(); }
1335 typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
1336 protocol_loc_iterator protocol_loc_begin() const {
1337 return ReferencedProtocols.loc_begin();
1339 protocol_loc_iterator protocol_loc_end() const {
1340 return ReferencedProtocols.loc_end();
1343 ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
1345 bool IsClassExtension() const { return getIdentifier() == 0; }
1346 const ObjCCategoryDecl *getNextClassExtension() const;
1348 bool hasSynthBitfield() const { return HasSynthBitfield; }
1349 void setHasSynthBitfield (bool val) { HasSynthBitfield = val; }
1351 typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
1352 ivar_iterator ivar_begin() const {
1353 return ivar_iterator(decls_begin());
1355 ivar_iterator ivar_end() const {
1356 return ivar_iterator(decls_end());
1358 unsigned ivar_size() const {
1359 return std::distance(ivar_begin(), ivar_end());
1361 bool ivar_empty() const {
1362 return ivar_begin() == ivar_end();
1365 SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
1366 void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; }
1368 void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
1369 SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
1370 void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
1371 SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
1373 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1374 static bool classof(const ObjCCategoryDecl *D) { return true; }
1375 static bool classofKind(Kind K) { return K == ObjCCategory; }
1377 friend class ASTDeclReader;
1378 friend class ASTDeclWriter;
1381 class ObjCImplDecl : public ObjCContainerDecl {
1382 virtual void anchor();
1384 /// Class interface for this class/category implementation
1385 ObjCInterfaceDecl *ClassInterface;
1388 ObjCImplDecl(Kind DK, DeclContext *DC,
1389 ObjCInterfaceDecl *classInterface,
1390 SourceLocation nameLoc, SourceLocation atStartLoc)
1391 : ObjCContainerDecl(DK, DC,
1392 classInterface? classInterface->getIdentifier() : 0,
1393 nameLoc, atStartLoc),
1394 ClassInterface(classInterface) {}
1397 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
1398 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
1399 void setClassInterface(ObjCInterfaceDecl *IFace);
1401 void addInstanceMethod(ObjCMethodDecl *method) {
1402 // FIXME: Context should be set correctly before we get here.
1403 method->setLexicalDeclContext(this);
1406 void addClassMethod(ObjCMethodDecl *method) {
1407 // FIXME: Context should be set correctly before we get here.
1408 method->setLexicalDeclContext(this);
1412 void addPropertyImplementation(ObjCPropertyImplDecl *property);
1414 ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
1415 ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
1417 // Iterator access to properties.
1418 typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
1419 propimpl_iterator propimpl_begin() const {
1420 return propimpl_iterator(decls_begin());
1422 propimpl_iterator propimpl_end() const {
1423 return propimpl_iterator(decls_end());
1426 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1427 static bool classof(const ObjCImplDecl *D) { return true; }
1428 static bool classofKind(Kind K) {
1429 return K >= firstObjCImpl && K <= lastObjCImpl;
1433 /// ObjCCategoryImplDecl - An object of this class encapsulates a category
1434 /// @implementation declaration. If a category class has declaration of a
1435 /// property, its implementation must be specified in the category's
1436 /// @implementation declaration. Example:
1437 /// @interface I @end
1438 /// @interface I(CATEGORY)
1439 /// @property int p1, d1;
1441 /// @implementation I(CATEGORY)
1445 /// ObjCCategoryImplDecl
1446 class ObjCCategoryImplDecl : public ObjCImplDecl {
1447 virtual void anchor();
1452 // Category name location
1453 SourceLocation CategoryNameLoc;
1455 ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id,
1456 ObjCInterfaceDecl *classInterface,
1457 SourceLocation nameLoc, SourceLocation atStartLoc,
1458 SourceLocation CategoryNameLoc)
1459 : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc),
1460 Id(Id), CategoryNameLoc(CategoryNameLoc) {}
1462 static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
1464 ObjCInterfaceDecl *classInterface,
1465 SourceLocation nameLoc,
1466 SourceLocation atStartLoc,
1467 SourceLocation CategoryNameLoc);
1468 static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1470 /// getIdentifier - Get the identifier that names the category
1471 /// interface associated with this implementation.
1472 /// FIXME: This is a bad API, we are overriding the NamedDecl::getIdentifier()
1473 /// to mean something different. For example:
1474 /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
1475 /// returns the class interface name, whereas
1476 /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
1477 /// returns the category name.
1478 IdentifierInfo *getIdentifier() const {
1481 void setIdentifier(IdentifierInfo *II) { Id = II; }
1483 ObjCCategoryDecl *getCategoryDecl() const;
1485 SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
1487 /// getName - Get the name of identifier for the class interface associated
1488 /// with this implementation as a StringRef.
1490 // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
1491 // something different.
1492 StringRef getName() const {
1493 return Id ? Id->getNameStart() : "";
1496 /// getNameAsCString - Get the name of identifier for the class
1497 /// interface associated with this implementation as a C string
1500 // FIXME: Deprecated, move clients to getName().
1501 const char *getNameAsCString() const {
1502 return Id ? Id->getNameStart() : "";
1505 /// @brief Get the name of the class associated with this interface.
1507 // FIXME: Deprecated, move clients to getName().
1508 std::string getNameAsString() const {
1512 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1513 static bool classof(const ObjCCategoryImplDecl *D) { return true; }
1514 static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
1516 friend class ASTDeclReader;
1517 friend class ASTDeclWriter;
1520 raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID);
1522 /// ObjCImplementationDecl - Represents a class definition - this is where
1523 /// method definitions are specified. For example:
1526 /// @implementation MyClass
1527 /// - (void)myMethod { /* do something */ }
1531 /// Typically, instance variables are specified in the class interface,
1532 /// *not* in the implementation. Nevertheless (for legacy reasons), we
1533 /// allow instance variables to be specified in the implementation. When
1534 /// specified, they need to be *identical* to the interface.
1536 class ObjCImplementationDecl : public ObjCImplDecl {
1537 virtual void anchor();
1538 /// Implementation Class's super class.
1539 ObjCInterfaceDecl *SuperClass;
1540 /// @implementation may have private ivars.
1541 SourceLocation IvarLBraceLoc;
1542 SourceLocation IvarRBraceLoc;
1544 /// Support for ivar initialization.
1545 /// IvarInitializers - The arguments used to initialize the ivars
1546 CXXCtorInitializer **IvarInitializers;
1547 unsigned NumIvarInitializers;
1549 /// true if class has a .cxx_[construct,destruct] method.
1550 bool HasCXXStructors : 1;
1552 /// true of class extension has at least one bitfield ivar.
1553 bool HasSynthBitfield : 1;
1555 ObjCImplementationDecl(DeclContext *DC,
1556 ObjCInterfaceDecl *classInterface,
1557 ObjCInterfaceDecl *superDecl,
1558 SourceLocation nameLoc, SourceLocation atStartLoc,
1559 SourceLocation IvarLBraceLoc=SourceLocation(),
1560 SourceLocation IvarRBraceLoc=SourceLocation())
1561 : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
1562 SuperClass(superDecl), IvarLBraceLoc(IvarLBraceLoc),
1563 IvarRBraceLoc(IvarRBraceLoc),
1564 IvarInitializers(0), NumIvarInitializers(0),
1565 HasCXXStructors(false), HasSynthBitfield(false){}
1567 static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
1568 ObjCInterfaceDecl *classInterface,
1569 ObjCInterfaceDecl *superDecl,
1570 SourceLocation nameLoc,
1571 SourceLocation atStartLoc,
1572 SourceLocation IvarLBraceLoc=SourceLocation(),
1573 SourceLocation IvarRBraceLoc=SourceLocation());
1575 static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1577 /// init_iterator - Iterates through the ivar initializer list.
1578 typedef CXXCtorInitializer **init_iterator;
1580 /// init_const_iterator - Iterates through the ivar initializer list.
1581 typedef CXXCtorInitializer * const * init_const_iterator;
1583 /// init_begin() - Retrieve an iterator to the first initializer.
1584 init_iterator init_begin() { return IvarInitializers; }
1585 /// begin() - Retrieve an iterator to the first initializer.
1586 init_const_iterator init_begin() const { return IvarInitializers; }
1588 /// init_end() - Retrieve an iterator past the last initializer.
1589 init_iterator init_end() {
1590 return IvarInitializers + NumIvarInitializers;
1592 /// end() - Retrieve an iterator past the last initializer.
1593 init_const_iterator init_end() const {
1594 return IvarInitializers + NumIvarInitializers;
1596 /// getNumArgs - Number of ivars which must be initialized.
1597 unsigned getNumIvarInitializers() const {
1598 return NumIvarInitializers;
1601 void setNumIvarInitializers(unsigned numNumIvarInitializers) {
1602 NumIvarInitializers = numNumIvarInitializers;
1605 void setIvarInitializers(ASTContext &C,
1606 CXXCtorInitializer ** initializers,
1607 unsigned numInitializers);
1609 bool hasCXXStructors() const { return HasCXXStructors; }
1610 void setHasCXXStructors(bool val) { HasCXXStructors = val; }
1612 bool hasSynthBitfield() const { return HasSynthBitfield; }
1613 void setHasSynthBitfield (bool val) { HasSynthBitfield = val; }
1615 /// getIdentifier - Get the identifier that names the class
1616 /// interface associated with this implementation.
1617 IdentifierInfo *getIdentifier() const {
1618 return getClassInterface()->getIdentifier();
1621 /// getName - Get the name of identifier for the class interface associated
1622 /// with this implementation as a StringRef.
1624 // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
1625 // something different.
1626 StringRef getName() const {
1627 assert(getIdentifier() && "Name is not a simple identifier");
1628 return getIdentifier()->getName();
1631 /// getNameAsCString - Get the name of identifier for the class
1632 /// interface associated with this implementation as a C string
1635 // FIXME: Move to StringRef API.
1636 const char *getNameAsCString() const {
1637 return getName().data();
1640 /// @brief Get the name of the class associated with this interface.
1642 // FIXME: Move to StringRef API.
1643 std::string getNameAsString() const {
1647 const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
1648 ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
1650 void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
1652 void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
1653 SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
1654 void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
1655 SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
1657 typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
1658 ivar_iterator ivar_begin() const {
1659 return ivar_iterator(decls_begin());
1661 ivar_iterator ivar_end() const {
1662 return ivar_iterator(decls_end());
1664 unsigned ivar_size() const {
1665 return std::distance(ivar_begin(), ivar_end());
1667 bool ivar_empty() const {
1668 return ivar_begin() == ivar_end();
1671 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1672 static bool classof(const ObjCImplementationDecl *D) { return true; }
1673 static bool classofKind(Kind K) { return K == ObjCImplementation; }
1675 friend class ASTDeclReader;
1676 friend class ASTDeclWriter;
1679 raw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID);
1681 /// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
1682 /// declared as @compatibility_alias alias class.
1683 class ObjCCompatibleAliasDecl : public NamedDecl {
1684 virtual void anchor();
1685 /// Class that this is an alias of.
1686 ObjCInterfaceDecl *AliasedClass;
1688 ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
1689 ObjCInterfaceDecl* aliasedClass)
1690 : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {}
1692 static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC,
1693 SourceLocation L, IdentifierInfo *Id,
1694 ObjCInterfaceDecl* aliasedClass);
1696 static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C,
1699 const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
1700 ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
1701 void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
1703 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1704 static bool classof(const ObjCCompatibleAliasDecl *D) { return true; }
1705 static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
1709 /// ObjCPropertyDecl - Represents one property declaration in an interface.
1711 /// @property (assign, readwrite) int MyProperty;
1713 class ObjCPropertyDecl : public NamedDecl {
1714 virtual void anchor();
1716 enum PropertyAttributeKind {
1717 OBJC_PR_noattr = 0x00,
1718 OBJC_PR_readonly = 0x01,
1719 OBJC_PR_getter = 0x02,
1720 OBJC_PR_assign = 0x04,
1721 OBJC_PR_readwrite = 0x08,
1722 OBJC_PR_retain = 0x10,
1723 OBJC_PR_copy = 0x20,
1724 OBJC_PR_nonatomic = 0x40,
1725 OBJC_PR_setter = 0x80,
1726 OBJC_PR_atomic = 0x100,
1727 OBJC_PR_weak = 0x200,
1728 OBJC_PR_strong = 0x400,
1729 OBJC_PR_unsafe_unretained = 0x800
1730 // Adding a property should change NumPropertyAttrsBits
1734 /// \brief Number of bits fitting all the property attributes.
1735 NumPropertyAttrsBits = 12
1738 enum SetterKind { Assign, Retain, Copy, Weak };
1739 enum PropertyControl { None, Required, Optional };
1741 SourceLocation AtLoc; // location of @property
1742 SourceLocation LParenLoc; // location of '(' starting attribute list or null.
1743 TypeSourceInfo *DeclType;
1744 unsigned PropertyAttributes : NumPropertyAttrsBits;
1745 unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
1746 // @required/@optional
1747 unsigned PropertyImplementation : 2;
1749 Selector GetterName; // getter name of NULL if no getter
1750 Selector SetterName; // setter name of NULL if no setter
1752 ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
1753 ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
1754 ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property
1756 ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
1757 SourceLocation AtLocation, SourceLocation LParenLocation,
1759 : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
1760 LParenLoc(LParenLocation), DeclType(T),
1761 PropertyAttributes(OBJC_PR_noattr),
1762 PropertyAttributesAsWritten(OBJC_PR_noattr),
1763 PropertyImplementation(None),
1764 GetterName(Selector()),
1765 SetterName(Selector()),
1766 GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {}
1768 static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
1770 IdentifierInfo *Id, SourceLocation AtLocation,
1771 SourceLocation LParenLocation,
1773 PropertyControl propControl = None);
1775 static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1777 SourceLocation getAtLoc() const { return AtLoc; }
1778 void setAtLoc(SourceLocation L) { AtLoc = L; }
1780 SourceLocation getLParenLoc() const { return LParenLoc; }
1781 void setLParenLoc(SourceLocation L) { LParenLoc = L; }
1783 TypeSourceInfo *getTypeSourceInfo() const { return DeclType; }
1784 QualType getType() const { return DeclType->getType(); }
1785 void setType(TypeSourceInfo *T) { DeclType = T; }
1787 PropertyAttributeKind getPropertyAttributes() const {
1788 return PropertyAttributeKind(PropertyAttributes);
1790 void setPropertyAttributes(PropertyAttributeKind PRVal) {
1791 PropertyAttributes |= PRVal;
1794 PropertyAttributeKind getPropertyAttributesAsWritten() const {
1795 return PropertyAttributeKind(PropertyAttributesAsWritten);
1798 bool hasWrittenStorageAttribute() const {
1799 return PropertyAttributesAsWritten & (OBJC_PR_assign | OBJC_PR_copy |
1800 OBJC_PR_unsafe_unretained | OBJC_PR_retain | OBJC_PR_strong |
1804 void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
1805 PropertyAttributesAsWritten = PRVal;
1808 void makeitReadWriteAttribute(void) {
1809 PropertyAttributes &= ~OBJC_PR_readonly;
1810 PropertyAttributes |= OBJC_PR_readwrite;
1813 // Helper methods for accessing attributes.
1815 /// isReadOnly - Return true iff the property has a setter.
1816 bool isReadOnly() const {
1817 return (PropertyAttributes & OBJC_PR_readonly);
1820 /// isAtomic - Return true if the property is atomic.
1821 bool isAtomic() const {
1822 return (PropertyAttributes & OBJC_PR_atomic);
1825 /// isRetaining - Return true if the property retains its value.
1826 bool isRetaining() const {
1827 return (PropertyAttributes &
1828 (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy));
1831 /// getSetterKind - Return the method used for doing assignment in
1832 /// the property setter. This is only valid if the property has been
1833 /// defined to have a setter.
1834 SetterKind getSetterKind() const {
1835 if (PropertyAttributes & OBJC_PR_strong)
1836 return getType()->isBlockPointerType() ? Copy : Retain;
1837 if (PropertyAttributes & OBJC_PR_retain)
1839 if (PropertyAttributes & OBJC_PR_copy)
1841 if (PropertyAttributes & OBJC_PR_weak)
1846 Selector getGetterName() const { return GetterName; }
1847 void setGetterName(Selector Sel) { GetterName = Sel; }
1849 Selector getSetterName() const { return SetterName; }
1850 void setSetterName(Selector Sel) { SetterName = Sel; }
1852 ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
1853 void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
1855 ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
1856 void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
1858 // Related to @optional/@required declared in @protocol
1859 void setPropertyImplementation(PropertyControl pc) {
1860 PropertyImplementation = pc;
1862 PropertyControl getPropertyImplementation() const {
1863 return PropertyControl(PropertyImplementation);
1866 void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
1867 PropertyIvarDecl = Ivar;
1869 ObjCIvarDecl *getPropertyIvarDecl() const {
1870 return PropertyIvarDecl;
1873 virtual SourceRange getSourceRange() const LLVM_READONLY {
1874 return SourceRange(AtLoc, getLocation());
1877 /// Lookup a property by name in the specified DeclContext.
1878 static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
1879 IdentifierInfo *propertyID);
1881 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1882 static bool classof(const ObjCPropertyDecl *D) { return true; }
1883 static bool classofKind(Kind K) { return K == ObjCProperty; }
1886 /// ObjCPropertyImplDecl - Represents implementation declaration of a property
1887 /// in a class or category implementation block. For example:
1888 /// @synthesize prop1 = ivar1;
1890 class ObjCPropertyImplDecl : public Decl {
1897 SourceLocation AtLoc; // location of @synthesize or @dynamic
1899 /// \brief For @synthesize, the location of the ivar, if it was written in
1900 /// the source code.
1903 /// @synthesize int a = b
1905 SourceLocation IvarLoc;
1907 /// Property declaration being implemented
1908 ObjCPropertyDecl *PropertyDecl;
1910 /// Null for @dynamic. Required for @synthesize.
1911 ObjCIvarDecl *PropertyIvarDecl;
1913 /// Null for @dynamic. Non-null if property must be copy-constructed in getter
1914 Expr *GetterCXXConstructor;
1916 /// Null for @dynamic. Non-null if property has assignment operator to call
1917 /// in Setter synthesis.
1918 Expr *SetterCXXAssignment;
1920 ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
1921 ObjCPropertyDecl *property,
1923 ObjCIvarDecl *ivarDecl,
1924 SourceLocation ivarLoc)
1925 : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
1926 IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl),
1927 GetterCXXConstructor(0), SetterCXXAssignment(0) {
1928 assert (PK == Dynamic || PropertyIvarDecl);
1932 static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC,
1933 SourceLocation atLoc, SourceLocation L,
1934 ObjCPropertyDecl *property,
1936 ObjCIvarDecl *ivarDecl,
1937 SourceLocation ivarLoc);
1939 static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1941 virtual SourceRange getSourceRange() const LLVM_READONLY;
1943 SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
1944 void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
1946 ObjCPropertyDecl *getPropertyDecl() const {
1947 return PropertyDecl;
1949 void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; }
1951 Kind getPropertyImplementation() const {
1952 return PropertyIvarDecl ? Synthesize : Dynamic;
1955 ObjCIvarDecl *getPropertyIvarDecl() const {
1956 return PropertyIvarDecl;
1958 SourceLocation getPropertyIvarDeclLoc() const { return IvarLoc; }
1960 void setPropertyIvarDecl(ObjCIvarDecl *Ivar,
1961 SourceLocation IvarLoc) {
1962 PropertyIvarDecl = Ivar;
1963 this->IvarLoc = IvarLoc;
1966 Expr *getGetterCXXConstructor() const {
1967 return GetterCXXConstructor;
1969 void setGetterCXXConstructor(Expr *getterCXXConstructor) {
1970 GetterCXXConstructor = getterCXXConstructor;
1973 Expr *getSetterCXXAssignment() const {
1974 return SetterCXXAssignment;
1976 void setSetterCXXAssignment(Expr *setterCXXAssignment) {
1977 SetterCXXAssignment = setterCXXAssignment;
1980 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1981 static bool classof(const ObjCPropertyImplDecl *D) { return true; }
1982 static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
1984 friend class ASTDeclReader;
1987 } // end namespace clang