clang API Documentation

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