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 "llvm/ADT/STLExtras.h"
27 class ObjCProtocolDecl
;
28 class ObjCCategoryDecl
;
29 class ObjCPropertyDecl
;
30 class ObjCPropertyImplDecl
;
31 class CXXBaseOrMemberInitializer
;
34 void operator=(const ObjCListBase
&); // DO NOT IMPLEMENT
35 ObjCListBase(const ObjCListBase
&); // DO NOT IMPLEMENT
37 /// List is an array of pointers to objects that are not owned by this object.
42 ObjCListBase() : List(0), NumElts(0) {}
43 unsigned size() const { return NumElts
; }
44 bool empty() const { return NumElts
== 0; }
47 void set(void *const* InList
, unsigned Elts
, ASTContext
&Ctx
);
51 /// ObjCList - This is a simple template class used to hold various lists of
52 /// decls etc, which is heavily used by the ObjC front-end. This only use case
53 /// this supports is setting the list all at once and then reading elements out
56 class ObjCList
: public ObjCListBase
{
58 void set(T
* const* InList
, unsigned Elts
, ASTContext
&Ctx
) {
59 ObjCListBase::set(reinterpret_cast<void*const*>(InList
), Elts
, Ctx
);
62 typedef T
* const * iterator
;
63 iterator
begin() const { return (iterator
)List
; }
64 iterator
end() const { return (iterator
)List
+NumElts
; }
66 T
* operator[](unsigned Idx
) const {
67 assert(Idx
< NumElts
&& "Invalid access");
72 /// \brief A list of Objective-C protocols, along with the source
73 /// locations at which they were referenced.
74 class ObjCProtocolList
: public ObjCList
<ObjCProtocolDecl
> {
75 SourceLocation
*Locations
;
77 using ObjCList
<ObjCProtocolDecl
>::set
;
80 ObjCProtocolList() : ObjCList
<ObjCProtocolDecl
>(), Locations(0) { }
82 typedef const SourceLocation
*loc_iterator
;
83 loc_iterator
loc_begin() const { return Locations
; }
84 loc_iterator
loc_end() const { return Locations
+ size(); }
86 void set(ObjCProtocolDecl
* const* InList
, unsigned Elts
,
87 const SourceLocation
*Locs
, ASTContext
&Ctx
);
91 /// ObjCMethodDecl - Represents an instance or class method declaration.
92 /// ObjC methods can be declared within 4 contexts: class interfaces,
93 /// categories, protocols, and class implementations. While C++ member
94 /// functions leverage C syntax, Objective-C method syntax is modeled after
95 /// Smalltalk (using colons to specify argument types/expressions).
96 /// Here are some brief examples:
98 /// Setter/getter instance methods:
99 /// - (void)setMenu:(NSMenu *)menu;
100 /// - (NSMenu *)menu;
102 /// Instance method that takes 2 NSView arguments:
103 /// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
105 /// Getter class method:
106 /// + (NSMenu *)defaultMenu;
108 /// A selector represents a unique name for a method. The selector names for
109 /// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
111 class ObjCMethodDecl
: public NamedDecl
, public DeclContext
{
113 enum ImplementationControl
{ None
, Required
, Optional
};
115 /// Bitfields must be first fields in this class so they pack with those
116 /// declared in class Decl.
117 /// instance (true) or class (false) method.
121 // Synthesized declaration method for a property setter/getter
122 bool IsSynthesized
: 1;
124 // Method has a definition.
127 // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
128 /// @required/@optional
129 unsigned DeclImplementation
: 2;
131 // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
133 unsigned objcDeclQualifier
: 6;
135 // Number of args separated by ':' in a method declaration.
136 unsigned NumSelectorArgs
;
138 // Result type of this method.
139 QualType MethodDeclType
;
141 // Type source information for the result type.
142 TypeSourceInfo
*ResultTInfo
;
144 /// ParamInfo - List of pointers to VarDecls for the formal parameters of this
146 ObjCList
<ParmVarDecl
> ParamInfo
;
148 /// List of attributes for this method declaration.
149 SourceLocation EndLoc
; // the location of the ';' or '}'.
151 // The following are only used for method definitions, null otherwise.
152 // FIXME: space savings opportunity, consider a sub-class.
155 /// SelfDecl - Decl for the implicit self parameter. This is lazily
156 /// constructed by createImplicitParams.
157 ImplicitParamDecl
*SelfDecl
;
158 /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily
159 /// constructed by createImplicitParams.
160 ImplicitParamDecl
*CmdDecl
;
162 ObjCMethodDecl(SourceLocation beginLoc
, SourceLocation endLoc
,
163 Selector SelInfo
, QualType T
,
164 TypeSourceInfo
*ResultTInfo
,
165 DeclContext
*contextDecl
,
166 bool isInstance
= true,
167 bool isVariadic
= false,
168 bool isSynthesized
= false,
169 bool isDefined
= false,
170 ImplementationControl impControl
= None
,
171 unsigned numSelectorArgs
= 0)
172 : NamedDecl(ObjCMethod
, contextDecl
, beginLoc
, SelInfo
),
173 DeclContext(ObjCMethod
),
174 IsInstance(isInstance
), IsVariadic(isVariadic
),
175 IsSynthesized(isSynthesized
),
176 IsDefined(isDefined
),
177 DeclImplementation(impControl
), objcDeclQualifier(OBJC_TQ_None
),
178 NumSelectorArgs(numSelectorArgs
), MethodDeclType(T
),
179 ResultTInfo(ResultTInfo
),
180 EndLoc(endLoc
), Body(0), SelfDecl(0), CmdDecl(0) {}
182 /// \brief A definition will return its interface declaration.
183 /// An interface declaration will return its definition.
184 /// Otherwise it will return itself.
185 virtual ObjCMethodDecl
*getNextRedeclaration();
188 static ObjCMethodDecl
*Create(ASTContext
&C
,
189 SourceLocation beginLoc
,
190 SourceLocation endLoc
, Selector SelInfo
,
192 TypeSourceInfo
*ResultTInfo
,
193 DeclContext
*contextDecl
,
194 bool isInstance
= true,
195 bool isVariadic
= false,
196 bool isSynthesized
= false,
197 bool isDefined
= false,
198 ImplementationControl impControl
= None
,
199 unsigned numSelectorArgs
= 0);
201 virtual ObjCMethodDecl
*getCanonicalDecl();
202 const ObjCMethodDecl
*getCanonicalDecl() const {
203 return const_cast<ObjCMethodDecl
*>(this)->getCanonicalDecl();
206 ObjCDeclQualifier
getObjCDeclQualifier() const {
207 return ObjCDeclQualifier(objcDeclQualifier
);
209 void setObjCDeclQualifier(ObjCDeclQualifier QV
) { objcDeclQualifier
= QV
; }
211 unsigned getNumSelectorArgs() const { return NumSelectorArgs
; }
212 void setNumSelectorArgs(unsigned numSelectorArgs
) {
213 NumSelectorArgs
= numSelectorArgs
;
216 // Location information, modeled after the Stmt API.
217 SourceLocation
getLocStart() const { return getLocation(); }
218 SourceLocation
getLocEnd() const { return EndLoc
; }
219 void setEndLoc(SourceLocation Loc
) { EndLoc
= Loc
; }
220 virtual SourceRange
getSourceRange() const {
221 return SourceRange(getLocation(), EndLoc
);
224 ObjCInterfaceDecl
*getClassInterface();
225 const ObjCInterfaceDecl
*getClassInterface() const {
226 return const_cast<ObjCMethodDecl
*>(this)->getClassInterface();
229 Selector
getSelector() const { return getDeclName().getObjCSelector(); }
231 QualType
getResultType() const { return MethodDeclType
; }
232 void setResultType(QualType T
) { MethodDeclType
= T
; }
234 /// \brief Determine the type of an expression that sends a message to this
236 QualType
getSendResultType() const {
237 return getResultType().getNonLValueExprType(getASTContext());
240 TypeSourceInfo
*getResultTypeSourceInfo() const { return ResultTInfo
; }
241 void setResultTypeSourceInfo(TypeSourceInfo
*TInfo
) { ResultTInfo
= TInfo
; }
243 // Iterator access to formal parameters.
244 unsigned param_size() const { return ParamInfo
.size(); }
245 typedef ObjCList
<ParmVarDecl
>::iterator param_iterator
;
246 param_iterator
param_begin() const { return ParamInfo
.begin(); }
247 param_iterator
param_end() const { return ParamInfo
.end(); }
248 // This method returns and of the parameters which are part of the selector
249 // name mangling requirements.
250 param_iterator
sel_param_end() const {
251 return ParamInfo
.begin() + NumSelectorArgs
;
254 void setMethodParams(ASTContext
&C
, ParmVarDecl
*const *List
, unsigned Num
,
255 unsigned numSelectorArgs
) {
256 ParamInfo
.set(List
, Num
, C
);
257 NumSelectorArgs
= numSelectorArgs
;
260 // Iterator access to parameter types.
261 typedef std::const_mem_fun_t
<QualType
, ParmVarDecl
> deref_fun
;
262 typedef llvm::mapped_iterator
<param_iterator
, deref_fun
> arg_type_iterator
;
264 arg_type_iterator
arg_type_begin() const {
265 return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType
));
267 arg_type_iterator
arg_type_end() const {
268 return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType
));
271 /// createImplicitParams - Used to lazily create the self and cmd
272 /// implict parameters. This must be called prior to using getSelfDecl()
273 /// or getCmdDecl(). The call is ignored if the implicit paramters
274 /// have already been created.
275 void createImplicitParams(ASTContext
&Context
, const ObjCInterfaceDecl
*ID
);
277 ImplicitParamDecl
* getSelfDecl() const { return SelfDecl
; }
278 void setSelfDecl(ImplicitParamDecl
*SD
) { SelfDecl
= SD
; }
279 ImplicitParamDecl
* getCmdDecl() const { return CmdDecl
; }
280 void setCmdDecl(ImplicitParamDecl
*CD
) { CmdDecl
= CD
; }
282 bool isInstanceMethod() const { return IsInstance
; }
283 void setInstanceMethod(bool isInst
) { IsInstance
= isInst
; }
284 bool isVariadic() const { return IsVariadic
; }
285 void setVariadic(bool isVar
) { IsVariadic
= isVar
; }
287 bool isClassMethod() const { return !IsInstance
; }
289 bool isSynthesized() const { return IsSynthesized
; }
290 void setSynthesized(bool isSynth
) { IsSynthesized
= isSynth
; }
292 bool isDefined() const { return IsDefined
; }
293 void setDefined(bool isDefined
) { IsDefined
= isDefined
; }
295 // Related to protocols declared in @protocol
296 void setDeclImplementation(ImplementationControl ic
) {
297 DeclImplementation
= ic
;
299 ImplementationControl
getImplementationControl() const {
300 return ImplementationControl(DeclImplementation
);
303 virtual Stmt
*getBody() const {
306 CompoundStmt
*getCompoundBody() { return (CompoundStmt
*)Body
; }
307 void setBody(Stmt
*B
) { Body
= B
; }
309 /// \brief Returns whether this specific method is a definition.
310 bool isThisDeclarationADefinition() const { return Body
; }
312 // Implement isa/cast/dyncast/etc.
313 static bool classof(const Decl
*D
) { return classofKind(D
->getKind()); }
314 static bool classof(const ObjCMethodDecl
*D
) { return true; }
315 static bool classofKind(Kind K
) { return K
== ObjCMethod
; }
316 static DeclContext
*castToDeclContext(const ObjCMethodDecl
*D
) {
317 return static_cast<DeclContext
*>(const_cast<ObjCMethodDecl
*>(D
));
319 static ObjCMethodDecl
*castFromDeclContext(const DeclContext
*DC
) {
320 return static_cast<ObjCMethodDecl
*>(const_cast<DeclContext
*>(DC
));
324 /// ObjCContainerDecl - Represents a container for method declarations.
325 /// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
326 /// ObjCProtocolDecl, and ObjCImplDecl.
328 class ObjCContainerDecl
: public NamedDecl
, public DeclContext
{
329 // These two locations in the range mark the end of the method container.
330 // The first points to the '@' token, and the second to the 'end' token.
334 ObjCContainerDecl(Kind DK
, DeclContext
*DC
, SourceLocation L
,
336 : NamedDecl(DK
, DC
, L
, Id
), DeclContext(DK
) {}
338 // Iterator access to properties.
339 typedef specific_decl_iterator
<ObjCPropertyDecl
> prop_iterator
;
340 prop_iterator
prop_begin() const {
341 return prop_iterator(decls_begin());
343 prop_iterator
prop_end() const {
344 return prop_iterator(decls_end());
347 // Iterator access to instance/class methods.
348 typedef specific_decl_iterator
<ObjCMethodDecl
> method_iterator
;
349 method_iterator
meth_begin() const {
350 return method_iterator(decls_begin());
352 method_iterator
meth_end() const {
353 return method_iterator(decls_end());
356 typedef filtered_decl_iterator
<ObjCMethodDecl
,
357 &ObjCMethodDecl::isInstanceMethod
>
359 instmeth_iterator
instmeth_begin() const {
360 return instmeth_iterator(decls_begin());
362 instmeth_iterator
instmeth_end() const {
363 return instmeth_iterator(decls_end());
366 typedef filtered_decl_iterator
<ObjCMethodDecl
,
367 &ObjCMethodDecl::isClassMethod
>
369 classmeth_iterator
classmeth_begin() const {
370 return classmeth_iterator(decls_begin());
372 classmeth_iterator
classmeth_end() const {
373 return classmeth_iterator(decls_end());
376 // Get the local instance/class method declared in this interface.
377 ObjCMethodDecl
*getMethod(Selector Sel
, bool isInstance
) const;
378 ObjCMethodDecl
*getInstanceMethod(Selector Sel
) const {
379 return getMethod(Sel
, true/*isInstance*/);
381 ObjCMethodDecl
*getClassMethod(Selector Sel
) const {
382 return getMethod(Sel
, false/*isInstance*/);
384 ObjCIvarDecl
*getIvarDecl(IdentifierInfo
*Id
) const;
386 ObjCPropertyDecl
*FindPropertyDeclaration(IdentifierInfo
*PropertyId
) const;
388 // Marks the end of the container.
389 SourceRange
getAtEndRange() const {
392 void setAtEndRange(SourceRange atEnd
) {
396 virtual SourceRange
getSourceRange() const {
397 return SourceRange(getLocation(), getAtEndRange().getEnd());
400 // Implement isa/cast/dyncast/etc.
401 static bool classof(const Decl
*D
) { return classofKind(D
->getKind()); }
402 static bool classof(const ObjCContainerDecl
*D
) { return true; }
403 static bool classofKind(Kind K
) {
404 return K
>= firstObjCContainer
&&
405 K
<= lastObjCContainer
;
408 static DeclContext
*castToDeclContext(const ObjCContainerDecl
*D
) {
409 return static_cast<DeclContext
*>(const_cast<ObjCContainerDecl
*>(D
));
411 static ObjCContainerDecl
*castFromDeclContext(const DeclContext
*DC
) {
412 return static_cast<ObjCContainerDecl
*>(const_cast<DeclContext
*>(DC
));
416 /// ObjCInterfaceDecl - Represents an ObjC class declaration. For example:
418 /// // MostPrimitive declares no super class (not particularly useful).
419 /// @interface MostPrimitive
420 /// // no instance variables or methods.
423 /// // NSResponder inherits from NSObject & implements NSCoding (a protocol).
424 /// @interface NSResponder : NSObject <NSCoding>
425 /// { // instance variables are represented by ObjCIvarDecl.
426 /// id nextResponder; // nextResponder instance variable.
428 /// - (NSResponder *)nextResponder; // return a pointer to NSResponder.
429 /// - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
430 /// @end // to an NSEvent.
432 /// Unlike C/C++, forward class declarations are accomplished with @class.
433 /// Unlike C/C++, @class allows for a list of classes to be forward declared.
434 /// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
435 /// typically inherit from NSObject (an exception is NSProxy).
437 class ObjCInterfaceDecl
: public ObjCContainerDecl
{
438 /// TypeForDecl - This indicates the Type object that represents this
439 /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
440 mutable Type
*TypeForDecl
;
441 friend class ASTContext
;
443 /// Class's super class.
444 ObjCInterfaceDecl
*SuperClass
;
446 /// Protocols referenced in the @interface declaration
447 ObjCProtocolList ReferencedProtocols
;
449 /// Protocols reference in both the @interface and class extensions.
450 ObjCList
<ObjCProtocolDecl
> AllReferencedProtocols
;
452 /// List of categories defined for this class.
453 /// FIXME: Why is this a linked list??
454 ObjCCategoryDecl
*CategoryList
;
456 /// IvarList - List of all ivars defined by this class; including class
457 /// extensions and implementation. This list is built lazily.
458 ObjCIvarDecl
*IvarList
;
460 bool ForwardDecl
:1; // declared with @class.
461 bool InternalInterface
:1; // true - no @interface for @implementation
463 SourceLocation ClassLoc
; // location of the class identifier.
464 SourceLocation SuperClassLoc
; // location of the super class identifier.
465 SourceLocation EndLoc
; // marks the '>', '}', or identifier.
467 ObjCInterfaceDecl(DeclContext
*DC
, SourceLocation atLoc
, IdentifierInfo
*Id
,
468 SourceLocation CLoc
, bool FD
, bool isInternal
);
471 static ObjCInterfaceDecl
*Create(ASTContext
&C
, DeclContext
*DC
,
472 SourceLocation atLoc
,
474 SourceLocation ClassLoc
= SourceLocation(),
475 bool ForwardDecl
= false,
476 bool isInternal
= false);
477 const ObjCProtocolList
&getReferencedProtocols() const {
478 return ReferencedProtocols
;
481 ObjCImplementationDecl
*getImplementation() const;
482 void setImplementation(ObjCImplementationDecl
*ImplD
);
484 ObjCCategoryDecl
*FindCategoryDeclaration(IdentifierInfo
*CategoryId
) const;
486 // Get the local instance/class method declared in a category.
487 ObjCMethodDecl
*getCategoryInstanceMethod(Selector Sel
) const;
488 ObjCMethodDecl
*getCategoryClassMethod(Selector Sel
) const;
489 ObjCMethodDecl
*getCategoryMethod(Selector Sel
, bool isInstance
) const {
490 return isInstance
? getInstanceMethod(Sel
)
491 : getClassMethod(Sel
);
494 typedef ObjCProtocolList::iterator protocol_iterator
;
496 protocol_iterator
protocol_begin() const {
497 return ReferencedProtocols
.begin();
499 protocol_iterator
protocol_end() const {
500 return ReferencedProtocols
.end();
503 typedef ObjCProtocolList::loc_iterator protocol_loc_iterator
;
505 protocol_loc_iterator
protocol_loc_begin() const {
506 return ReferencedProtocols
.loc_begin();
509 protocol_loc_iterator
protocol_loc_end() const {
510 return ReferencedProtocols
.loc_end();
513 typedef ObjCList
<ObjCProtocolDecl
>::iterator all_protocol_iterator
;
515 all_protocol_iterator
all_referenced_protocol_begin() const {
516 return AllReferencedProtocols
.empty() ? protocol_begin()
517 : AllReferencedProtocols
.begin();
519 all_protocol_iterator
all_referenced_protocol_end() const {
520 return AllReferencedProtocols
.empty() ? protocol_end()
521 : AllReferencedProtocols
.end();
524 typedef specific_decl_iterator
<ObjCIvarDecl
> ivar_iterator
;
526 ivar_iterator
ivar_begin() const { return ivar_iterator(decls_begin()); }
527 ivar_iterator
ivar_end() const { return ivar_iterator(decls_end()); }
529 unsigned ivar_size() const {
530 return std::distance(ivar_begin(), ivar_end());
533 bool ivar_empty() const { return ivar_begin() == ivar_end(); }
535 ObjCIvarDecl
*all_declared_ivar_begin();
536 void setIvarList(ObjCIvarDecl
*ivar
) { IvarList
= ivar
; }
538 /// setProtocolList - Set the list of protocols that this interface
540 void setProtocolList(ObjCProtocolDecl
*const* List
, unsigned Num
,
541 const SourceLocation
*Locs
, ASTContext
&C
) {
542 ReferencedProtocols
.set(List
, Num
, Locs
, C
);
545 /// mergeClassExtensionProtocolList - Merge class extension's protocol list
546 /// into the protocol list for this class.
547 void mergeClassExtensionProtocolList(ObjCProtocolDecl
*const* List
,
551 bool isForwardDecl() const { return ForwardDecl
; }
552 void setForwardDecl(bool val
) { ForwardDecl
= val
; }
554 ObjCInterfaceDecl
*getSuperClass() const { return SuperClass
; }
555 void setSuperClass(ObjCInterfaceDecl
* superCls
) { SuperClass
= superCls
; }
557 ObjCCategoryDecl
* getCategoryList() const { return CategoryList
; }
558 void setCategoryList(ObjCCategoryDecl
*category
) {
559 CategoryList
= category
;
562 ObjCCategoryDecl
* getFirstClassExtension() const;
565 *FindPropertyVisibleInPrimaryClass(IdentifierInfo
*PropertyId
) const;
567 /// isSuperClassOf - Return true if this class is the specified class or is a
568 /// super class of the specified interface class.
569 bool isSuperClassOf(const ObjCInterfaceDecl
*I
) const {
570 // If RHS is derived from LHS it is OK; else it is not OK.
574 I
= I
->getSuperClass();
579 ObjCIvarDecl
*lookupInstanceVariable(IdentifierInfo
*IVarName
,
580 ObjCInterfaceDecl
*&ClassDeclared
);
581 ObjCIvarDecl
*lookupInstanceVariable(IdentifierInfo
*IVarName
) {
582 ObjCInterfaceDecl
*ClassDeclared
;
583 return lookupInstanceVariable(IVarName
, ClassDeclared
);
586 // Lookup a method. First, we search locally. If a method isn't
587 // found, we search referenced protocols and class categories.
588 ObjCMethodDecl
*lookupMethod(Selector Sel
, bool isInstance
) const;
589 ObjCMethodDecl
*lookupInstanceMethod(Selector Sel
) const {
590 return lookupMethod(Sel
, true/*isInstance*/);
592 ObjCMethodDecl
*lookupClassMethod(Selector Sel
) const {
593 return lookupMethod(Sel
, false/*isInstance*/);
595 ObjCInterfaceDecl
*lookupInheritedClass(const IdentifierInfo
*ICName
);
597 // Lookup a method in the classes implementation hierarchy.
598 ObjCMethodDecl
*lookupPrivateInstanceMethod(const Selector
&Sel
);
600 // Location information, modeled after the Stmt API.
601 SourceLocation
getLocStart() const { return getLocation(); } // '@'interface
602 SourceLocation
getLocEnd() const { return EndLoc
; }
603 void setLocEnd(SourceLocation LE
) { EndLoc
= LE
; }
605 void setClassLoc(SourceLocation Loc
) { ClassLoc
= Loc
; }
606 SourceLocation
getClassLoc() const { return ClassLoc
; }
607 void setSuperClassLoc(SourceLocation Loc
) { SuperClassLoc
= Loc
; }
608 SourceLocation
getSuperClassLoc() const { return SuperClassLoc
; }
610 /// isImplicitInterfaceDecl - check that this is an implicitly declared
611 /// ObjCInterfaceDecl node. This is for legacy objective-c @implementation
612 /// declaration without an @interface declaration.
613 bool isImplicitInterfaceDecl() const { return InternalInterface
; }
614 void setImplicitInterfaceDecl(bool val
) { InternalInterface
= val
; }
616 /// ClassImplementsProtocol - Checks that 'lProto' protocol
617 /// has been implemented in IDecl class, its super class or categories (if
618 /// lookupCategory is true).
619 bool ClassImplementsProtocol(ObjCProtocolDecl
*lProto
,
621 bool RHSIsQualifiedID
= false);
623 // Low-level accessor
624 Type
*getTypeForDecl() const { return TypeForDecl
; }
625 void setTypeForDecl(Type
*TD
) const { TypeForDecl
= TD
; }
627 static bool classof(const Decl
*D
) { return classofKind(D
->getKind()); }
628 static bool classof(const ObjCInterfaceDecl
*D
) { return true; }
629 static bool classofKind(Kind K
) { return K
== ObjCInterface
; }
631 friend class ASTDeclReader
;
632 friend class ASTDeclWriter
;
635 /// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
636 /// instance variables are identical to C. The only exception is Objective-C
637 /// supports C++ style access control. For example:
639 /// @interface IvarExample : NSObject
641 /// id defaultToProtected;
643 /// id canBePublic; // same as C++.
645 /// id canBeProtected; // same as C++.
647 /// id canBePackage; // framework visibility (not available in C++).
650 class ObjCIvarDecl
: public FieldDecl
{
653 None
, Private
, Protected
, Public
, Package
657 ObjCIvarDecl(ObjCContainerDecl
*DC
, SourceLocation L
, IdentifierInfo
*Id
,
658 QualType T
, TypeSourceInfo
*TInfo
, AccessControl ac
, Expr
*BW
,
660 : FieldDecl(ObjCIvar
, DC
, L
, Id
, T
, TInfo
, BW
, /*Mutable=*/false),
661 NextIvar(0), DeclAccess(ac
), Synthesized(synthesized
) {}
664 static ObjCIvarDecl
*Create(ASTContext
&C
, ObjCContainerDecl
*DC
,
665 SourceLocation L
, IdentifierInfo
*Id
, QualType T
,
666 TypeSourceInfo
*TInfo
,
667 AccessControl ac
, Expr
*BW
= NULL
,
668 bool synthesized
=false);
670 /// \brief Return the class interface that this ivar is logically contained
671 /// in; this is either the interface where the ivar was declared, or the
672 /// interface the ivar is conceptually a part of in the case of synthesized
674 const ObjCInterfaceDecl
*getContainingInterface() const;
676 ObjCIvarDecl
*getNextIvar() { return NextIvar
; }
677 void setNextIvar(ObjCIvarDecl
*ivar
) { NextIvar
= ivar
; }
679 void setAccessControl(AccessControl ac
) { DeclAccess
= ac
; }
681 AccessControl
getAccessControl() const { return AccessControl(DeclAccess
); }
683 AccessControl
getCanonicalAccessControl() const {
684 return DeclAccess
== None
? Protected
: AccessControl(DeclAccess
);
687 void setSynthesize(bool synth
) { Synthesized
= synth
; }
688 bool getSynthesize() const { return Synthesized
; }
690 // Implement isa/cast/dyncast/etc.
691 static bool classof(const Decl
*D
) { return classofKind(D
->getKind()); }
692 static bool classof(const ObjCIvarDecl
*D
) { return true; }
693 static bool classofKind(Kind K
) { return K
== ObjCIvar
; }
695 /// NextIvar - Next Ivar in the list of ivars declared in class; class's
696 /// extensions and class's implementation
697 ObjCIvarDecl
*NextIvar
;
699 // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
700 unsigned DeclAccess
: 3;
701 unsigned Synthesized
: 1;
705 /// ObjCAtDefsFieldDecl - Represents a field declaration created by an
707 class ObjCAtDefsFieldDecl
: public FieldDecl
{
709 ObjCAtDefsFieldDecl(DeclContext
*DC
, SourceLocation L
, IdentifierInfo
*Id
,
710 QualType T
, Expr
*BW
)
711 : FieldDecl(ObjCAtDefsField
, DC
, L
, Id
, T
,
712 /*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ?
713 BW
, /*Mutable=*/false) {}
716 static ObjCAtDefsFieldDecl
*Create(ASTContext
&C
, DeclContext
*DC
,
718 IdentifierInfo
*Id
, QualType T
,
721 // Implement isa/cast/dyncast/etc.
722 static bool classof(const Decl
*D
) { return classofKind(D
->getKind()); }
723 static bool classof(const ObjCAtDefsFieldDecl
*D
) { return true; }
724 static bool classofKind(Kind K
) { return K
== ObjCAtDefsField
; }
727 /// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols
728 /// declare a pure abstract type (i.e no instance variables are permitted).
729 /// Protocols orginally drew inspiration from C++ pure virtual functions (a C++
730 /// feature with nice semantics and lousy syntax:-). Here is an example:
732 /// @protocol NSDraggingInfo <refproto1, refproto2>
733 /// - (NSWindow *)draggingDestinationWindow;
734 /// - (NSImage *)draggedImage;
737 /// This says that NSDraggingInfo requires two methods and requires everything
738 /// that the two "referenced protocols" 'refproto1' and 'refproto2' require as
741 /// @interface ImplementsNSDraggingInfo : NSObject <NSDraggingInfo>
744 /// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
745 /// protocols are in distinct namespaces. For example, Cocoa defines both
746 /// an NSObject protocol and class (which isn't allowed in Java). As a result,
747 /// protocols are referenced using angle brackets as follows:
749 /// id <NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
751 class ObjCProtocolDecl
: public ObjCContainerDecl
{
752 /// Referenced protocols
753 ObjCProtocolList ReferencedProtocols
;
755 bool isForwardProtoDecl
; // declared with @protocol.
757 SourceLocation EndLoc
; // marks the '>' or identifier.
759 ObjCProtocolDecl(DeclContext
*DC
, SourceLocation L
, IdentifierInfo
*Id
)
760 : ObjCContainerDecl(ObjCProtocol
, DC
, L
, Id
),
761 isForwardProtoDecl(true) {
765 static ObjCProtocolDecl
*Create(ASTContext
&C
, DeclContext
*DC
,
766 SourceLocation L
, IdentifierInfo
*Id
);
768 const ObjCProtocolList
&getReferencedProtocols() const {
769 return ReferencedProtocols
;
771 typedef ObjCProtocolList::iterator protocol_iterator
;
772 protocol_iterator
protocol_begin() const {return ReferencedProtocols
.begin();}
773 protocol_iterator
protocol_end() const { return ReferencedProtocols
.end(); }
774 typedef ObjCProtocolList::loc_iterator protocol_loc_iterator
;
775 protocol_loc_iterator
protocol_loc_begin() const {
776 return ReferencedProtocols
.loc_begin();
778 protocol_loc_iterator
protocol_loc_end() const {
779 return ReferencedProtocols
.loc_end();
781 unsigned protocol_size() const { return ReferencedProtocols
.size(); }
783 /// setProtocolList - Set the list of protocols that this interface
785 void setProtocolList(ObjCProtocolDecl
*const*List
, unsigned Num
,
786 const SourceLocation
*Locs
, ASTContext
&C
) {
787 ReferencedProtocols
.set(List
, Num
, Locs
, C
);
790 ObjCProtocolDecl
*lookupProtocolNamed(IdentifierInfo
*PName
);
792 // Lookup a method. First, we search locally. If a method isn't
793 // found, we search referenced protocols and class categories.
794 ObjCMethodDecl
*lookupMethod(Selector Sel
, bool isInstance
) const;
795 ObjCMethodDecl
*lookupInstanceMethod(Selector Sel
) const {
796 return lookupMethod(Sel
, true/*isInstance*/);
798 ObjCMethodDecl
*lookupClassMethod(Selector Sel
) const {
799 return lookupMethod(Sel
, false/*isInstance*/);
802 bool isForwardDecl() const { return isForwardProtoDecl
; }
803 void setForwardDecl(bool val
) { isForwardProtoDecl
= val
; }
805 // Location information, modeled after the Stmt API.
806 SourceLocation
getLocStart() const { return getLocation(); } // '@'protocol
807 SourceLocation
getLocEnd() const { return EndLoc
; }
808 void setLocEnd(SourceLocation LE
) { EndLoc
= LE
; }
810 static bool classof(const Decl
*D
) { return classofKind(D
->getKind()); }
811 static bool classof(const ObjCProtocolDecl
*D
) { return true; }
812 static bool classofKind(Kind K
) { return K
== ObjCProtocol
; }
815 /// ObjCClassDecl - Specifies a list of forward class declarations. For example:
817 /// @class NSCursor, NSImage, NSPasteboard, NSWindow;
819 class ObjCClassDecl
: public Decl
{
822 ObjCInterfaceDecl
*ID
;
825 ObjCClassRef(ObjCInterfaceDecl
*d
, SourceLocation l
) : ID(d
), L(l
) {}
826 SourceLocation
getLocation() const { return L
; }
827 ObjCInterfaceDecl
*getInterface() const { return ID
; }
830 ObjCClassRef
*ForwardDecls
;
833 ObjCClassDecl(DeclContext
*DC
, SourceLocation L
,
834 ObjCInterfaceDecl
*const *Elts
, const SourceLocation
*Locs
,
835 unsigned nElts
, ASTContext
&C
);
837 static ObjCClassDecl
*Create(ASTContext
&C
, DeclContext
*DC
, SourceLocation L
,
838 ObjCInterfaceDecl
*const *Elts
= 0,
839 const SourceLocation
*Locs
= 0,
842 virtual SourceRange
getSourceRange() const;
844 typedef const ObjCClassRef
* iterator
;
845 iterator
begin() const { return ForwardDecls
; }
846 iterator
end() const { return ForwardDecls
+ NumDecls
; }
847 unsigned size() const { return NumDecls
; }
849 /// setClassList - Set the list of forward classes.
850 void setClassList(ASTContext
&C
, ObjCInterfaceDecl
*const*List
,
851 const SourceLocation
*Locs
, unsigned Num
);
853 static bool classof(const Decl
*D
) { return classofKind(D
->getKind()); }
854 static bool classof(const ObjCClassDecl
*D
) { return true; }
855 static bool classofKind(Kind K
) { return K
== ObjCClass
; }
858 /// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations.
861 /// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo;
863 class ObjCForwardProtocolDecl
: public Decl
{
864 ObjCProtocolList ReferencedProtocols
;
866 ObjCForwardProtocolDecl(DeclContext
*DC
, SourceLocation L
,
867 ObjCProtocolDecl
*const *Elts
, unsigned nElts
,
868 const SourceLocation
*Locs
, ASTContext
&C
);
871 static ObjCForwardProtocolDecl
*Create(ASTContext
&C
, DeclContext
*DC
,
873 ObjCProtocolDecl
*const *Elts
,
875 const SourceLocation
*Locs
);
877 static ObjCForwardProtocolDecl
*Create(ASTContext
&C
, DeclContext
*DC
,
879 return Create(C
, DC
, L
, 0, 0, 0);
882 typedef ObjCProtocolList::iterator protocol_iterator
;
883 protocol_iterator
protocol_begin() const {return ReferencedProtocols
.begin();}
884 protocol_iterator
protocol_end() const { return ReferencedProtocols
.end(); }
885 typedef ObjCProtocolList::loc_iterator protocol_loc_iterator
;
886 protocol_loc_iterator
protocol_loc_begin() const {
887 return ReferencedProtocols
.loc_begin();
889 protocol_loc_iterator
protocol_loc_end() const {
890 return ReferencedProtocols
.loc_end();
893 unsigned protocol_size() const { return ReferencedProtocols
.size(); }
895 /// setProtocolList - Set the list of forward protocols.
896 void setProtocolList(ObjCProtocolDecl
*const*List
, unsigned Num
,
897 const SourceLocation
*Locs
, ASTContext
&C
) {
898 ReferencedProtocols
.set(List
, Num
, Locs
, C
);
900 static bool classof(const Decl
*D
) { return classofKind(D
->getKind()); }
901 static bool classof(const ObjCForwardProtocolDecl
*D
) { return true; }
902 static bool classofKind(Kind K
) { return K
== ObjCForwardProtocol
; }
905 /// ObjCCategoryDecl - Represents a category declaration. A category allows
906 /// you to add methods to an existing class (without subclassing or modifying
907 /// the original class interface or implementation:-). Categories don't allow
908 /// you to add instance data. The following example adds "myMethod" to all
909 /// NSView's within a process:
911 /// @interface NSView (MyViewMethods)
915 /// Categories also allow you to split the implementation of a class across
916 /// several files (a feature more naturally supported in C++).
918 /// Categories were originally inspired by dynamic languages such as Common
919 /// Lisp and Smalltalk. More traditional class-based languages (C++, Java)
920 /// don't support this level of dynamism, which is both powerful and dangerous.
922 class ObjCCategoryDecl
: public ObjCContainerDecl
{
923 /// Interface belonging to this category
924 ObjCInterfaceDecl
*ClassInterface
;
926 /// referenced protocols in this category.
927 ObjCProtocolList ReferencedProtocols
;
929 /// Next category belonging to this class.
930 /// FIXME: this should not be a singly-linked list. Move storage elsewhere.
931 ObjCCategoryDecl
*NextClassCategory
;
933 /// true of class extension has at least one bitfield ivar.
934 bool HasSynthBitfield
: 1;
936 /// \brief The location of the '@' in '@interface'
937 SourceLocation AtLoc
;
939 /// \brief The location of the category name in this declaration.
940 SourceLocation CategoryNameLoc
;
942 ObjCCategoryDecl(DeclContext
*DC
, SourceLocation AtLoc
,
943 SourceLocation ClassNameLoc
, SourceLocation CategoryNameLoc
,
945 : ObjCContainerDecl(ObjCCategory
, DC
, ClassNameLoc
, Id
),
946 ClassInterface(0), NextClassCategory(0), HasSynthBitfield(false),
947 AtLoc(AtLoc
), CategoryNameLoc(CategoryNameLoc
) {
951 static ObjCCategoryDecl
*Create(ASTContext
&C
, DeclContext
*DC
,
952 SourceLocation AtLoc
,
953 SourceLocation ClassNameLoc
,
954 SourceLocation CategoryNameLoc
,
957 ObjCInterfaceDecl
*getClassInterface() { return ClassInterface
; }
958 const ObjCInterfaceDecl
*getClassInterface() const { return ClassInterface
; }
959 void setClassInterface(ObjCInterfaceDecl
*IDecl
) { ClassInterface
= IDecl
; }
961 ObjCCategoryImplDecl
*getImplementation() const;
962 void setImplementation(ObjCCategoryImplDecl
*ImplD
);
964 /// setProtocolList - Set the list of protocols that this interface
966 void setProtocolList(ObjCProtocolDecl
*const*List
, unsigned Num
,
967 const SourceLocation
*Locs
, ASTContext
&C
) {
968 ReferencedProtocols
.set(List
, Num
, Locs
, C
);
971 const ObjCProtocolList
&getReferencedProtocols() const {
972 return ReferencedProtocols
;
975 typedef ObjCProtocolList::iterator protocol_iterator
;
976 protocol_iterator
protocol_begin() const {return ReferencedProtocols
.begin();}
977 protocol_iterator
protocol_end() const { return ReferencedProtocols
.end(); }
978 unsigned protocol_size() const { return ReferencedProtocols
.size(); }
979 typedef ObjCProtocolList::loc_iterator protocol_loc_iterator
;
980 protocol_loc_iterator
protocol_loc_begin() const {
981 return ReferencedProtocols
.loc_begin();
983 protocol_loc_iterator
protocol_loc_end() const {
984 return ReferencedProtocols
.loc_end();
987 ObjCCategoryDecl
*getNextClassCategory() const { return NextClassCategory
; }
988 void setNextClassCategory(ObjCCategoryDecl
*Cat
) {
989 NextClassCategory
= Cat
;
991 void insertNextClassCategory() {
992 NextClassCategory
= ClassInterface
->getCategoryList();
993 ClassInterface
->setCategoryList(this);
994 ClassInterface
->setChangedSinceDeserialization(true);
997 bool IsClassExtension() const { return getIdentifier() == 0; }
998 const ObjCCategoryDecl
*getNextClassExtension() const;
1000 bool hasSynthBitfield() const { return HasSynthBitfield
; }
1001 void setHasSynthBitfield (bool val
) { HasSynthBitfield
= val
; }
1003 typedef specific_decl_iterator
<ObjCIvarDecl
> ivar_iterator
;
1004 ivar_iterator
ivar_begin() const {
1005 return ivar_iterator(decls_begin());
1007 ivar_iterator
ivar_end() const {
1008 return ivar_iterator(decls_end());
1010 unsigned ivar_size() const {
1011 return std::distance(ivar_begin(), ivar_end());
1013 bool ivar_empty() const {
1014 return ivar_begin() == ivar_end();
1017 SourceLocation
getAtLoc() const { return AtLoc
; }
1018 void setAtLoc(SourceLocation At
) { AtLoc
= At
; }
1020 SourceLocation
getCategoryNameLoc() const { return CategoryNameLoc
; }
1021 void setCategoryNameLoc(SourceLocation Loc
) { CategoryNameLoc
= Loc
; }
1023 virtual SourceRange
getSourceRange() const {
1024 return SourceRange(AtLoc
, getAtEndRange().getEnd());
1027 static bool classof(const Decl
*D
) { return classofKind(D
->getKind()); }
1028 static bool classof(const ObjCCategoryDecl
*D
) { return true; }
1029 static bool classofKind(Kind K
) { return K
== ObjCCategory
; }
1032 class ObjCImplDecl
: public ObjCContainerDecl
{
1033 /// Class interface for this class/category implementation
1034 ObjCInterfaceDecl
*ClassInterface
;
1037 ObjCImplDecl(Kind DK
, DeclContext
*DC
, SourceLocation L
,
1038 ObjCInterfaceDecl
*classInterface
)
1039 : ObjCContainerDecl(DK
, DC
, L
,
1040 classInterface
? classInterface
->getIdentifier() : 0),
1041 ClassInterface(classInterface
) {}
1044 const ObjCInterfaceDecl
*getClassInterface() const { return ClassInterface
; }
1045 ObjCInterfaceDecl
*getClassInterface() { return ClassInterface
; }
1046 void setClassInterface(ObjCInterfaceDecl
*IFace
);
1048 void addInstanceMethod(ObjCMethodDecl
*method
) {
1049 // FIXME: Context should be set correctly before we get here.
1050 method
->setLexicalDeclContext(this);
1053 void addClassMethod(ObjCMethodDecl
*method
) {
1054 // FIXME: Context should be set correctly before we get here.
1055 method
->setLexicalDeclContext(this);
1059 void addPropertyImplementation(ObjCPropertyImplDecl
*property
);
1061 ObjCPropertyImplDecl
*FindPropertyImplDecl(IdentifierInfo
*propertyId
) const;
1062 ObjCPropertyImplDecl
*FindPropertyImplIvarDecl(IdentifierInfo
*ivarId
) const;
1064 // Iterator access to properties.
1065 typedef specific_decl_iterator
<ObjCPropertyImplDecl
> propimpl_iterator
;
1066 propimpl_iterator
propimpl_begin() const {
1067 return propimpl_iterator(decls_begin());
1069 propimpl_iterator
propimpl_end() const {
1070 return propimpl_iterator(decls_end());
1073 static bool classof(const Decl
*D
) { return classofKind(D
->getKind()); }
1074 static bool classof(const ObjCImplDecl
*D
) { return true; }
1075 static bool classofKind(Kind K
) {
1076 return K
>= firstObjCImpl
&& K
<= lastObjCImpl
;
1080 /// ObjCCategoryImplDecl - An object of this class encapsulates a category
1081 /// @implementation declaration. If a category class has declaration of a
1082 /// property, its implementation must be specified in the category's
1083 /// @implementation declaration. Example:
1084 /// @interface I @end
1085 /// @interface I(CATEGORY)
1086 /// @property int p1, d1;
1088 /// @implementation I(CATEGORY)
1092 /// ObjCCategoryImplDecl
1093 class ObjCCategoryImplDecl
: public ObjCImplDecl
{
1097 ObjCCategoryImplDecl(DeclContext
*DC
, SourceLocation L
, IdentifierInfo
*Id
,
1098 ObjCInterfaceDecl
*classInterface
)
1099 : ObjCImplDecl(ObjCCategoryImpl
, DC
, L
, classInterface
), Id(Id
) {}
1101 static ObjCCategoryImplDecl
*Create(ASTContext
&C
, DeclContext
*DC
,
1102 SourceLocation L
, IdentifierInfo
*Id
,
1103 ObjCInterfaceDecl
*classInterface
);
1105 /// getIdentifier - Get the identifier that names the category
1106 /// interface associated with this implementation.
1107 /// FIXME: This is a bad API, we are overriding the NamedDecl::getIdentifier()
1108 /// to mean something different. For example:
1109 /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
1110 /// returns the class interface name, whereas
1111 /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
1112 /// returns the category name.
1113 IdentifierInfo
*getIdentifier() const {
1116 void setIdentifier(IdentifierInfo
*II
) { Id
= II
; }
1118 ObjCCategoryDecl
*getCategoryDecl() const;
1120 /// getName - Get the name of identifier for the class interface associated
1121 /// with this implementation as a StringRef.
1123 // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
1124 // something different.
1125 llvm::StringRef
getName() const {
1126 return Id
? Id
->getNameStart() : "";
1129 /// getNameAsCString - Get the name of identifier for the class
1130 /// interface associated with this implementation as a C string
1133 // FIXME: Deprecated, move clients to getName().
1134 const char *getNameAsCString() const {
1135 return Id
? Id
->getNameStart() : "";
1138 /// @brief Get the name of the class associated with this interface.
1140 // FIXME: Deprecated, move clients to getName().
1141 std::string
getNameAsString() const {
1145 static bool classof(const Decl
*D
) { return classofKind(D
->getKind()); }
1146 static bool classof(const ObjCCategoryImplDecl
*D
) { return true; }
1147 static bool classofKind(Kind K
) { return K
== ObjCCategoryImpl
;}
1150 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&OS
,
1151 const ObjCCategoryImplDecl
*CID
);
1153 /// ObjCImplementationDecl - Represents a class definition - this is where
1154 /// method definitions are specified. For example:
1157 /// @implementation MyClass
1158 /// - (void)myMethod { /* do something */ }
1162 /// Typically, instance variables are specified in the class interface,
1163 /// *not* in the implementation. Nevertheless (for legacy reasons), we
1164 /// allow instance variables to be specified in the implementation. When
1165 /// specified, they need to be *identical* to the interface.
1167 class ObjCImplementationDecl
: public ObjCImplDecl
{
1168 /// Implementation Class's super class.
1169 ObjCInterfaceDecl
*SuperClass
;
1170 /// Support for ivar initialization.
1171 /// IvarInitializers - The arguments used to initialize the ivars
1172 CXXBaseOrMemberInitializer
**IvarInitializers
;
1173 unsigned NumIvarInitializers
;
1175 /// true of class extension has at least one bitfield ivar.
1176 bool HasSynthBitfield
: 1;
1178 ObjCImplementationDecl(DeclContext
*DC
, SourceLocation L
,
1179 ObjCInterfaceDecl
*classInterface
,
1180 ObjCInterfaceDecl
*superDecl
)
1181 : ObjCImplDecl(ObjCImplementation
, DC
, L
, classInterface
),
1182 SuperClass(superDecl
), IvarInitializers(0), NumIvarInitializers(0),
1183 HasSynthBitfield(false) {}
1185 static ObjCImplementationDecl
*Create(ASTContext
&C
, DeclContext
*DC
,
1187 ObjCInterfaceDecl
*classInterface
,
1188 ObjCInterfaceDecl
*superDecl
);
1190 /// init_iterator - Iterates through the ivar initializer list.
1191 typedef CXXBaseOrMemberInitializer
**init_iterator
;
1193 /// init_const_iterator - Iterates through the ivar initializer list.
1194 typedef CXXBaseOrMemberInitializer
* const * init_const_iterator
;
1196 /// init_begin() - Retrieve an iterator to the first initializer.
1197 init_iterator
init_begin() { return IvarInitializers
; }
1198 /// begin() - Retrieve an iterator to the first initializer.
1199 init_const_iterator
init_begin() const { return IvarInitializers
; }
1201 /// init_end() - Retrieve an iterator past the last initializer.
1202 init_iterator
init_end() {
1203 return IvarInitializers
+ NumIvarInitializers
;
1205 /// end() - Retrieve an iterator past the last initializer.
1206 init_const_iterator
init_end() const {
1207 return IvarInitializers
+ NumIvarInitializers
;
1209 /// getNumArgs - Number of ivars which must be initialized.
1210 unsigned getNumIvarInitializers() const {
1211 return NumIvarInitializers
;
1214 void setNumIvarInitializers(unsigned numNumIvarInitializers
) {
1215 NumIvarInitializers
= numNumIvarInitializers
;
1218 void setIvarInitializers(ASTContext
&C
,
1219 CXXBaseOrMemberInitializer
** initializers
,
1220 unsigned numInitializers
);
1222 bool hasSynthBitfield() const { return HasSynthBitfield
; }
1223 void setHasSynthBitfield (bool val
) { HasSynthBitfield
= val
; }
1225 /// getIdentifier - Get the identifier that names the class
1226 /// interface associated with this implementation.
1227 IdentifierInfo
*getIdentifier() const {
1228 return getClassInterface()->getIdentifier();
1231 /// getName - Get the name of identifier for the class interface associated
1232 /// with this implementation as a StringRef.
1234 // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
1235 // something different.
1236 llvm::StringRef
getName() const {
1237 assert(getIdentifier() && "Name is not a simple identifier");
1238 return getIdentifier()->getName();
1241 /// getNameAsCString - Get the name of identifier for the class
1242 /// interface associated with this implementation as a C string
1245 // FIXME: Move to StringRef API.
1246 const char *getNameAsCString() const {
1247 return getName().data();
1250 /// @brief Get the name of the class associated with this interface.
1252 // FIXME: Move to StringRef API.
1253 std::string
getNameAsString() const {
1257 const ObjCInterfaceDecl
*getSuperClass() const { return SuperClass
; }
1258 ObjCInterfaceDecl
*getSuperClass() { return SuperClass
; }
1260 void setSuperClass(ObjCInterfaceDecl
* superCls
) { SuperClass
= superCls
; }
1262 typedef specific_decl_iterator
<ObjCIvarDecl
> ivar_iterator
;
1263 ivar_iterator
ivar_begin() const {
1264 return ivar_iterator(decls_begin());
1266 ivar_iterator
ivar_end() const {
1267 return ivar_iterator(decls_end());
1269 unsigned ivar_size() const {
1270 return std::distance(ivar_begin(), ivar_end());
1272 bool ivar_empty() const {
1273 return ivar_begin() == ivar_end();
1276 static bool classof(const Decl
*D
) { return classofKind(D
->getKind()); }
1277 static bool classof(const ObjCImplementationDecl
*D
) { return true; }
1278 static bool classofKind(Kind K
) { return K
== ObjCImplementation
; }
1280 friend class ASTDeclReader
;
1281 friend class ASTDeclWriter
;
1284 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&OS
,
1285 const ObjCImplementationDecl
*ID
);
1287 /// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
1288 /// declared as @compatibility_alias alias class.
1289 class ObjCCompatibleAliasDecl
: public NamedDecl
{
1290 /// Class that this is an alias of.
1291 ObjCInterfaceDecl
*AliasedClass
;
1293 ObjCCompatibleAliasDecl(DeclContext
*DC
, SourceLocation L
, IdentifierInfo
*Id
,
1294 ObjCInterfaceDecl
* aliasedClass
)
1295 : NamedDecl(ObjCCompatibleAlias
, DC
, L
, Id
), AliasedClass(aliasedClass
) {}
1297 static ObjCCompatibleAliasDecl
*Create(ASTContext
&C
, DeclContext
*DC
,
1298 SourceLocation L
, IdentifierInfo
*Id
,
1299 ObjCInterfaceDecl
* aliasedClass
);
1301 const ObjCInterfaceDecl
*getClassInterface() const { return AliasedClass
; }
1302 ObjCInterfaceDecl
*getClassInterface() { return AliasedClass
; }
1303 void setClassInterface(ObjCInterfaceDecl
*D
) { AliasedClass
= D
; }
1305 static bool classof(const Decl
*D
) { return classofKind(D
->getKind()); }
1306 static bool classof(const ObjCCompatibleAliasDecl
*D
) { return true; }
1307 static bool classofKind(Kind K
) { return K
== ObjCCompatibleAlias
; }
1311 /// ObjCPropertyDecl - Represents one property declaration in an interface.
1313 /// @property (assign, readwrite) int MyProperty;
1315 class ObjCPropertyDecl
: public NamedDecl
{
1317 enum PropertyAttributeKind
{
1318 OBJC_PR_noattr
= 0x00,
1319 OBJC_PR_readonly
= 0x01,
1320 OBJC_PR_getter
= 0x02,
1321 OBJC_PR_assign
= 0x04,
1322 OBJC_PR_readwrite
= 0x08,
1323 OBJC_PR_retain
= 0x10,
1324 OBJC_PR_copy
= 0x20,
1325 OBJC_PR_nonatomic
= 0x40,
1326 OBJC_PR_setter
= 0x80
1329 enum SetterKind
{ Assign
, Retain
, Copy
};
1330 enum PropertyControl
{ None
, Required
, Optional
};
1332 SourceLocation AtLoc
; // location of @property
1333 TypeSourceInfo
*DeclType
;
1334 unsigned PropertyAttributes
: 8;
1335 unsigned PropertyAttributesAsWritten
: 8;
1336 // @required/@optional
1337 unsigned PropertyImplementation
: 2;
1339 Selector GetterName
; // getter name of NULL if no getter
1340 Selector SetterName
; // setter name of NULL if no setter
1342 ObjCMethodDecl
*GetterMethodDecl
; // Declaration of getter instance method
1343 ObjCMethodDecl
*SetterMethodDecl
; // Declaration of setter instance method
1344 ObjCIvarDecl
*PropertyIvarDecl
; // Synthesize ivar for this property
1346 ObjCPropertyDecl(DeclContext
*DC
, SourceLocation L
, IdentifierInfo
*Id
,
1347 SourceLocation AtLocation
, TypeSourceInfo
*T
)
1348 : NamedDecl(ObjCProperty
, DC
, L
, Id
), AtLoc(AtLocation
), DeclType(T
),
1349 PropertyAttributes(OBJC_PR_noattr
),
1350 PropertyAttributesAsWritten(OBJC_PR_noattr
),
1351 PropertyImplementation(None
),
1352 GetterName(Selector()),
1353 SetterName(Selector()),
1354 GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {}
1356 static ObjCPropertyDecl
*Create(ASTContext
&C
, DeclContext
*DC
,
1358 IdentifierInfo
*Id
, SourceLocation AtLocation
,
1360 PropertyControl propControl
= None
);
1361 SourceLocation
getAtLoc() const { return AtLoc
; }
1362 void setAtLoc(SourceLocation L
) { AtLoc
= L
; }
1364 TypeSourceInfo
*getTypeSourceInfo() const { return DeclType
; }
1365 QualType
getType() const { return DeclType
->getType(); }
1366 void setType(TypeSourceInfo
*T
) { DeclType
= T
; }
1368 PropertyAttributeKind
getPropertyAttributes() const {
1369 return PropertyAttributeKind(PropertyAttributes
);
1371 void setPropertyAttributes(PropertyAttributeKind PRVal
) {
1372 PropertyAttributes
|= PRVal
;
1375 PropertyAttributeKind
getPropertyAttributesAsWritten() const {
1376 return PropertyAttributeKind(PropertyAttributesAsWritten
);
1379 void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal
) {
1380 PropertyAttributesAsWritten
= PRVal
;
1383 void makeitReadWriteAttribute(void) {
1384 PropertyAttributes
&= ~OBJC_PR_readonly
;
1385 PropertyAttributes
|= OBJC_PR_readwrite
;
1388 // Helper methods for accessing attributes.
1390 /// isReadOnly - Return true iff the property has a setter.
1391 bool isReadOnly() const {
1392 return (PropertyAttributes
& OBJC_PR_readonly
);
1395 /// getSetterKind - Return the method used for doing assignment in
1396 /// the property setter. This is only valid if the property has been
1397 /// defined to have a setter.
1398 SetterKind
getSetterKind() const {
1399 if (PropertyAttributes
& OBJC_PR_retain
)
1401 if (PropertyAttributes
& OBJC_PR_copy
)
1406 Selector
getGetterName() const { return GetterName
; }
1407 void setGetterName(Selector Sel
) { GetterName
= Sel
; }
1409 Selector
getSetterName() const { return SetterName
; }
1410 void setSetterName(Selector Sel
) { SetterName
= Sel
; }
1412 ObjCMethodDecl
*getGetterMethodDecl() const { return GetterMethodDecl
; }
1413 void setGetterMethodDecl(ObjCMethodDecl
*gDecl
) { GetterMethodDecl
= gDecl
; }
1415 ObjCMethodDecl
*getSetterMethodDecl() const { return SetterMethodDecl
; }
1416 void setSetterMethodDecl(ObjCMethodDecl
*gDecl
) { SetterMethodDecl
= gDecl
; }
1418 // Related to @optional/@required declared in @protocol
1419 void setPropertyImplementation(PropertyControl pc
) {
1420 PropertyImplementation
= pc
;
1422 PropertyControl
getPropertyImplementation() const {
1423 return PropertyControl(PropertyImplementation
);
1426 void setPropertyIvarDecl(ObjCIvarDecl
*Ivar
) {
1427 PropertyIvarDecl
= Ivar
;
1429 ObjCIvarDecl
*getPropertyIvarDecl() const {
1430 return PropertyIvarDecl
;
1433 /// Lookup a property by name in the specified DeclContext.
1434 static ObjCPropertyDecl
*findPropertyDecl(const DeclContext
*DC
,
1435 IdentifierInfo
*propertyID
);
1437 static bool classof(const Decl
*D
) { return classofKind(D
->getKind()); }
1438 static bool classof(const ObjCPropertyDecl
*D
) { return true; }
1439 static bool classofKind(Kind K
) { return K
== ObjCProperty
; }
1442 /// ObjCPropertyImplDecl - Represents implementation declaration of a property
1443 /// in a class or category implementation block. For example:
1444 /// @synthesize prop1 = ivar1;
1446 class ObjCPropertyImplDecl
: public Decl
{
1453 SourceLocation AtLoc
; // location of @synthesize or @dynamic
1454 /// Property declaration being implemented
1455 ObjCPropertyDecl
*PropertyDecl
;
1457 /// Null for @dynamic. Required for @synthesize.
1458 ObjCIvarDecl
*PropertyIvarDecl
;
1460 /// Null for @dynamic. Non-null if property must be copy-constructed in getter
1461 Expr
*GetterCXXConstructor
;
1463 /// Null for @dynamic. Non-null if property has assignment operator to call
1464 /// in Setter synthesis.
1465 Expr
*SetterCXXAssignment
;
1467 ObjCPropertyImplDecl(DeclContext
*DC
, SourceLocation atLoc
, SourceLocation L
,
1468 ObjCPropertyDecl
*property
,
1470 ObjCIvarDecl
*ivarDecl
)
1471 : Decl(ObjCPropertyImpl
, DC
, L
), AtLoc(atLoc
),
1472 PropertyDecl(property
), PropertyIvarDecl(ivarDecl
),
1473 GetterCXXConstructor(0), SetterCXXAssignment(0) {
1474 assert (PK
== Dynamic
|| PropertyIvarDecl
);
1478 static ObjCPropertyImplDecl
*Create(ASTContext
&C
, DeclContext
*DC
,
1479 SourceLocation atLoc
, SourceLocation L
,
1480 ObjCPropertyDecl
*property
,
1482 ObjCIvarDecl
*ivarDecl
);
1484 virtual SourceRange
getSourceRange() const {
1485 return SourceRange(AtLoc
, getLocation());
1487 SourceLocation
getLocStart() const { return AtLoc
; }
1488 void setAtLoc(SourceLocation Loc
) { AtLoc
= Loc
; }
1490 ObjCPropertyDecl
*getPropertyDecl() const {
1491 return PropertyDecl
;
1493 void setPropertyDecl(ObjCPropertyDecl
*Prop
) { PropertyDecl
= Prop
; }
1495 Kind
getPropertyImplementation() const {
1496 return PropertyIvarDecl
? Synthesize
: Dynamic
;
1499 ObjCIvarDecl
*getPropertyIvarDecl() const {
1500 return PropertyIvarDecl
;
1502 void setPropertyIvarDecl(ObjCIvarDecl
*Ivar
) { PropertyIvarDecl
= Ivar
; }
1504 Expr
*getGetterCXXConstructor() const {
1505 return GetterCXXConstructor
;
1507 void setGetterCXXConstructor(Expr
*getterCXXConstructor
) {
1508 GetterCXXConstructor
= getterCXXConstructor
;
1511 Expr
*getSetterCXXAssignment() const {
1512 return SetterCXXAssignment
;
1514 void setSetterCXXAssignment(Expr
*setterCXXAssignment
) {
1515 SetterCXXAssignment
= setterCXXAssignment
;
1518 static bool classof(const Decl
*D
) { return classofKind(D
->getKind()); }
1519 static bool classof(const ObjCPropertyImplDecl
*D
) { return true; }
1520 static bool classofKind(Decl::Kind K
) { return K
== ObjCPropertyImpl
; }
1523 } // end namespace clang