DeclObjC.h revision faf5e779d16bb4590f2a97e1c7ded255eddd90f3
1980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff//===--- DeclObjC.h - Classes for representing declarations -----*- C++ -*-===//
2980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff//
3980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff//                     The LLVM Compiler Infrastructure
4980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
7980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff//
8980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff//===----------------------------------------------------------------------===//
9980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff//
10980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff//  This file defines the DeclObjC interface and subclasses.
11980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff//
12980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff//===----------------------------------------------------------------------===//
13980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
14980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff#ifndef LLVM_CLANG_AST_DECLOBJC_H
15980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff#define LLVM_CLANG_AST_DECLOBJC_H
16980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
17980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff#include "clang/AST/Decl.h"
18c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#include "clang/Basic/IdentifierTable.h"
19980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
20980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffnamespace clang {
21980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass Expr;
22980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass Stmt;
23980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass FunctionDecl;
24980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass AttributeList;
25a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCIvarDecl;
26a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCMethodDecl;
27a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCProtocolDecl;
28a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCCategoryDecl;
29a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCPropertyDecl;
3058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
31a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCMethodDecl - Represents an instance or class method declaration.
3258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// ObjC methods can be declared within 4 contexts: class interfaces,
3358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// categories, protocols, and class implementations. While C++ member
3458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// functions leverage C syntax, Objective-C method syntax is modeled after
3558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// Smalltalk (using colons to specify argument types/expressions).
3658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// Here are some brief examples:
3758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff///
3858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// Setter/getter instance methods:
3958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// - (void)setMenu:(NSMenu *)menu;
4058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// - (NSMenu *)menu;
4158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff///
4258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// Instance method that takes 2 NSView arguments:
4358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
4458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff///
4558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// Getter class method:
4658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// + (NSMenu *)defaultMenu;
4758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff///
4858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// A selector represents a unique name for a method. The selector names for
4958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
5058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff///
51a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCMethodDecl : public Decl {
5258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroffpublic:
5358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  enum ImplementationControl { None, Required, Optional };
5458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroffprivate:
5558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// Bitfields must be first fields in this class so they pack with those
5658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// declared in class Decl.
5758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// instance (true) or class (false) method.
5858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  bool IsInstance : 1;
5958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  bool IsVariadic : 1;
6058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
6158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// @required/@optional
6258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  ImplementationControl DeclImplementation : 2;
6358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
6458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// in, inout, etc.
65a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCDeclQualifier objcDeclQualifier : 6;
6658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
6758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Context this method is declared in.
6858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  NamedDecl *MethodContext;
6958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
7058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // A unigue name for this method.
7158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  Selector SelName;
7258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
7358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Type of this method.
7458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  QualType MethodDeclType;
7558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
7658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// parameters of this Method.  This is null if there are no formals.
7758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  ParmVarDecl **ParamInfo;
7858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  int NumMethodParams;  // -1 if no parameters
7958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
8058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// List of attributes for this method declaration.
8158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  AttributeList *MethodAttrs;
8258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
8358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  SourceLocation EndLoc; // the location of the ';' or '{'.
8458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
8558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // The following are only used for method definitions, null otherwise.
8658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // FIXME: space savings opportunity, consider a sub-class.
8758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  Stmt *Body;
8858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  ParmVarDecl *SelfDecl;
8958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroffpublic:
90a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
9158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff                 Selector SelInfo, QualType T,
9258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff                 Decl *contextDecl,
9358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff                 ParmVarDecl **paramInfo = 0, int numParams=-1,
9458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff                 AttributeList *M = 0, bool isInstance = true,
9558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff                 bool isVariadic = false,
9658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff                 ImplementationControl impControl = None,
9758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff                 Decl *PrevDecl = 0)
98a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  : Decl(ObjCMethod, beginLoc),
9958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    IsInstance(isInstance), IsVariadic(isVariadic),
10058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
10158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    MethodContext(static_cast<NamedDecl*>(contextDecl)),
10258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    SelName(SelInfo), MethodDeclType(T),
10358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    ParamInfo(paramInfo), NumMethodParams(numParams),
10458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    MethodAttrs(M), EndLoc(endLoc), Body(0), SelfDecl(0) {}
105a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  virtual ~ObjCMethodDecl();
10658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
107a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCDeclQualifier getObjCDeclQualifier() const { return objcDeclQualifier; }
108a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
10958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
11058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Location information, modeled after the Stmt API.
11158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  SourceLocation getLocStart() const { return getLocation(); }
11258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
11358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
11458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  NamedDecl *getMethodContext() const { return MethodContext; }
11558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
116a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *const getClassInterface() const;
11758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
11858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  Selector getSelector() const { return SelName; }
119faf5e779d16bb4590f2a97e1c7ded255eddd90f3Fariborz Jahanian  unsigned getSynthesizedMethodSize() const;
12058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  QualType getResultType() const { return MethodDeclType; }
12158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
122d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  // Iterator access to formal parameters.
123d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  unsigned param_size() const {
124d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner    return NumMethodParams == -1 ? 0 : NumMethodParams;
125d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  }
126d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  typedef ParmVarDecl **param_iterator;
127d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  typedef ParmVarDecl * const *param_const_iterator;
128d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  param_iterator param_begin() { return ParamInfo; }
129d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  param_iterator param_end() { return ParamInfo+param_size(); }
130d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  param_const_iterator param_begin() const { return ParamInfo; }
131d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  param_const_iterator param_end() const { return ParamInfo+param_size(); }
132d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner
13358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  int getNumParams() const { return NumMethodParams; }
13458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  ParmVarDecl *getParamDecl(int i) const {
13558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    assert(i < getNumParams() && "Illegal param #");
13658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    return ParamInfo[i];
13758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
13858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  void setMethodParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
13958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
14058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  AttributeList *getMethodAttrs() const {return MethodAttrs;}
14158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  bool isInstance() const { return IsInstance; }
14258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  bool isVariadic() const { return IsVariadic; }
14358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
14458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Related to protocols declared in  @protocol
14558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  void setDeclImplementation(ImplementationControl ic) {
14658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    DeclImplementation = ic;
14758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
14858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  ImplementationControl getImplementationControl() const {
14958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    return DeclImplementation;
15058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
15158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  Stmt *const getBody() const { return Body; }
15258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  void setBody(Stmt *B) { Body = B; }
15358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
15458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  ParmVarDecl *const getSelfDecl() const { return SelfDecl; }
15558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  void setSelfDecl(ParmVarDecl *PVD) { SelfDecl = PVD; }
15658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
15758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Implement isa/cast/dyncast/etc.
158a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCMethod; }
159a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCMethodDecl *D) { return true; }
16058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff};
161b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian
162a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCInterfaceDecl - Represents an ObjC class declaration. For example:
1630c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
1640c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   // MostPrimitive declares no super class (not particularly useful).
1650c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @interface MostPrimitive
1660c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     // no instance variables or methods.
1670c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @end
1680c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
169fd5de471478a507dd2495c4ea9bcab801ea5fa65Chris Lattner///   // NSResponder inherits from NSObject & implements NSCoding (a protocol).
1700c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @interface NSResponder : NSObject <NSCoding>
171a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek///   { // instance variables are represented by ObjCIvarDecl.
1720c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id nextResponder; // nextResponder instance variable.
1730c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   }
1740c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   - (NSResponder *)nextResponder; // return a pointer to NSResponder.
1750c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
1760c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @end                                    // to an NSEvent.
1770c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
1780c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   Unlike C/C++, forward class declarations are accomplished with @class.
1790c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   Unlike C/C++, @class allows for a list of classes to be forward declared.
1800c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
1810c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   typically inherit from NSObject (an exception is NSProxy).
1820c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
183a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCInterfaceDecl : public TypeDecl {
184980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
185980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Class's super class.
186a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *SuperClass;
187980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
188980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Protocols referenced in interface header declaration
189a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl **ReferencedProtocols;  // Null if none
190c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian  unsigned NumReferencedProtocols;  // 0 if none
191980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
192980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Ivars/NumIvars - This is a new[]'d array of pointers to Decls.
193a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCIvarDecl **Ivars;   // Null if not defined.
194980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  int NumIvars;   // -1 if not defined.
195980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
196980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// instance methods
197a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl **InstanceMethods;  // Null if not defined
1987ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumInstanceMethods;  // -1 if not defined
199980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
200980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// class methods
201a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl **ClassMethods;  // Null if not defined
2027ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumClassMethods;  // -1 if not defined
203980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
204980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// List of categories defined for this class.
205a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryDecl *CategoryList;
20682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
20782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  /// class properties
208a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCPropertyDecl **PropertyDecl;  // Null if no property
20982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  int NumPropertyDecl;  // -1 if no property
210980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
2113a3ca1b35a7121aea0bf465a192dce748465e10fFariborz Jahanian  bool ForwardDecl:1; // declared with @class.
2123a3ca1b35a7121aea0bf465a192dce748465e10fFariborz Jahanian  bool InternalInterface:1; // true - no @interface for @implementation
21360fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff
214f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  SourceLocation EndLoc; // marks the '>', '}', or identifier.
215f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  SourceLocation AtEndLoc; // marks the end of the entire interface.
216980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffpublic:
217a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl(SourceLocation atLoc, unsigned numRefProtos,
2183a3ca1b35a7121aea0bf465a192dce748465e10fFariborz Jahanian                    IdentifierInfo *Id, bool FD = false,
2193a3ca1b35a7121aea0bf465a192dce748465e10fFariborz Jahanian                    bool isInternal = false)
220a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    : TypeDecl(ObjCInterface, atLoc, Id, 0), SuperClass(0),
221c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian      ReferencedProtocols(0), NumReferencedProtocols(0), Ivars(0),
2227ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      NumIvars(-1),
2237ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      InstanceMethods(0), NumInstanceMethods(-1),
2247ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      ClassMethods(0), NumClassMethods(-1),
22582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian      CategoryList(0), PropertyDecl(0), NumPropertyDecl(-1),
22682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian      ForwardDecl(FD), InternalInterface(isInternal) {
227980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff        AllocIntfRefProtocols(numRefProtos);
228980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      }
229a5997c4f36e0f5aa44623a5b1e3b914760d1ec68Steve Naroff
230a5997c4f36e0f5aa44623a5b1e3b914760d1ec68Steve Naroff  // This is necessary when converting a forward declaration to a definition.
231980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void AllocIntfRefProtocols(unsigned numRefProtos) {
232980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    if (numRefProtos) {
233a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ReferencedProtocols = new ObjCProtocolDecl*[numRefProtos];
2347ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      memset(ReferencedProtocols, '\0',
235a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek             numRefProtos*sizeof(ObjCProtocolDecl*));
2367ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      NumReferencedProtocols = numRefProtos;
237980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    }
238980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
239980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
240a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl **getReferencedProtocols() const {
2417ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    return ReferencedProtocols;
2427ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  }
243c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian  unsigned getNumIntfRefProtocols() const { return NumReferencedProtocols; }
244980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
2450330071714f1ba09e926becd666f4fc0ed62bc0bSteve Naroff  int getNumInstanceVariables() const { return NumIvars; }
246980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
247a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef ObjCIvarDecl * const *ivar_iterator;
2485564e07af5e62875f3b83fc2e5a8823588b5adeaChris Lattner  unsigned ivar_size() const { return NumIvars == -1 ?0 : NumIvars; }
249be6df088d69bca0e99c7845a6cd8c1ca85034f31Chris Lattner  ivar_iterator ivar_begin() const { return Ivars; }
2505564e07af5e62875f3b83fc2e5a8823588b5adeaChris Lattner  ivar_iterator ivar_end() const { return Ivars + ivar_size();}
251be6df088d69bca0e99c7845a6cd8c1ca85034f31Chris Lattner
2527ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumInstanceMethods() const { return NumInstanceMethods; }
2537ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumClassMethods() const { return NumClassMethods; }
254980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
255a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef ObjCMethodDecl * const * instmeth_iterator;
2564c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  instmeth_iterator instmeth_begin() const { return InstanceMethods; }
2574c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  instmeth_iterator instmeth_end() const {
25823c3bb768fd3eb24ff1a7402856405129afac0e3Chris Lattner    return InstanceMethods+(NumInstanceMethods == -1 ? 0 : NumInstanceMethods);
2594c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  }
2604c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner
261a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef ObjCMethodDecl * const * classmeth_iterator;
2624c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  classmeth_iterator classmeth_begin() const { return ClassMethods; }
2634c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  classmeth_iterator classmeth_end() const {
26423c3bb768fd3eb24ff1a7402856405129afac0e3Chris Lattner    return ClassMethods+(NumClassMethods == -1 ? 0 : NumClassMethods);
2654c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  }
2664c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner
267a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void addInstanceVariablesToClass(ObjCIvarDecl **ivars, unsigned numIvars,
26860fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff                                   SourceLocation RBracLoc);
269980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
270a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
271a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                  ObjCMethodDecl **clsMethods, unsigned numClsMembers,
27260fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff                  SourceLocation AtEnd);
273980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
274768f26ee5892cd63ff0335a15d71a2385ba7c5eaSteve Naroff  bool isForwardDecl() const { return ForwardDecl; }
275768f26ee5892cd63ff0335a15d71a2385ba7c5eaSteve Naroff  void setForwardDecl(bool val) { ForwardDecl = val; }
276980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
277a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setIntfRefProtocols(unsigned idx, ObjCProtocolDecl *OID) {
2787ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    assert((idx < NumReferencedProtocols) && "index out of range");
2797ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    ReferencedProtocols[idx] = OID;
280980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
281980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
282a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
283a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
284980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
285a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryDecl* getCategoryList() const { return CategoryList; }
286a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setCategoryList(ObjCCategoryDecl *category) {
2873d58138992b9bc7b34aaa680f3ddf3971292eb7dSteve Naroff         CategoryList = category;
288980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
289a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *ivarName,
290a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                                       ObjCInterfaceDecl *&clsDeclared);
29158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
29258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Get the local instance method declared in this interface.
293a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getInstanceMethod(Selector &Sel) {
29458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    for (instmeth_iterator I = instmeth_begin(), E = instmeth_end();
29558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff	     I != E; ++I) {
29658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff      if ((*I)->getSelector() == Sel)
29758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff        return *I;
29858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    }
29958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff	return 0;
30058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
30158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Get the local class method declared in this interface.
302a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getClassMethod(Selector &Sel) {
30358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
30458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff	     I != E; ++I) {
30558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff      if ((*I)->getSelector() == Sel)
30658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff        return *I;
30758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    }
30858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff	return 0;
30958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
31094a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // Lookup a method. First, we search locally. If a method isn't
31194a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // found, we search referenced protocols and class categories.
312a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *lookupInstanceMethod(Selector Sel);
313a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *lookupClassMethod(Selector Sel);
31460fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff
315f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  // Location information, modeled after the Stmt API.
31660fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff  SourceLocation getLocStart() const { return getLocation(); } // '@'interface
317f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
318f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
31960fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff
32060fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff  // We also need to record the @end location.
321f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  SourceLocation getAtEndLoc() const { return AtEndLoc; }
32282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
323ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  int getNumPropertyDecl() const { return NumPropertyDecl; }
32482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  void setNumPropertyDecl(int num) { NumPropertyDecl = num; }
32582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
326a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCPropertyDecl **const getPropertyDecl() const { return PropertyDecl; }
327a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCPropertyDecl **getPropertyDecl() { return PropertyDecl; }
328a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setPropertyDecls(ObjCPropertyDecl **properties) {
32982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian    PropertyDecl = properties;
33082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  }
331f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff
3324b6df3fa953267c5d755628c8afd818bb571e579Fariborz Jahanian  /// ImplicitInterfaceDecl - check that this is an implicitely declared
333a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  /// ObjCInterfaceDecl node. This is for legacy objective-c @implementation
3344b6df3fa953267c5d755628c8afd818bb571e579Fariborz Jahanian  /// declaration without an @interface declaration.
3353a3ca1b35a7121aea0bf465a192dce748465e10fFariborz Jahanian  bool ImplicitInterfaceDecl() const { return InternalInterface; }
3364b6df3fa953267c5d755628c8afd818bb571e579Fariborz Jahanian
337a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCInterface; }
338a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCInterfaceDecl *D) { return true; }
339980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
340980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
341a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
3420c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// instance variables are identical to C. The only exception is Objective-C
3430c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// supports C++ style access control. For example:
3440c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
3450c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @interface IvarExample : NSObject
3460c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   {
3470c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id defaultToPrivate; // same as C++.
3480c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @public:
3490c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id canBePublic; // same as C++.
3500c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @protected:
3510c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id canBeProtected; // same as C++.
3520c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @package:
3530c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id canBePackage; // framework visibility (not available in C++).
3540c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   }
3550c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
356a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCIvarDecl : public FieldDecl {
357980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffpublic:
358a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCIvarDecl(SourceLocation L, IdentifierInfo *Id, QualType T)
359a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    : FieldDecl(ObjCIvar, L, Id, T) {}
360980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
361980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  enum AccessControl {
362980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    None, Private, Protected, Public, Package
363980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  };
364980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void setAccessControl(AccessControl ac) { DeclAccess = ac; }
365980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  AccessControl getAccessControl() const { return DeclAccess; }
366980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
367980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  // Implement isa/cast/dyncast/etc.
368a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCIvar; }
369a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCIvarDecl *D) { return true; }
370980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffprivate:
371980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  AccessControl DeclAccess : 3;
372980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
373980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
374980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
375a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols
3760c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// declare a pure abstract type (i.e no instance variables are permitted).
3770c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Protocols orginally drew inspiration from C++ pure virtual functions (a C++
3780c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// feature with nice semantics and lousy syntax:-). Here is an example:
3790c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
3800c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @protocol NSDraggingInfo
3810c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - (NSWindow *)draggingDestinationWindow;
3820c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - (NSImage *)draggedImage;
3830c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @end
3840c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
3850c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @interface ImplementsNSDraggingInfo : NSObject <NSDraggingInfo>
3860c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @end
3870c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
388a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
3890c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// protocols are in distinct namespaces. For example, Cocoa defines both
3900c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// an NSObject protocol and class (which isn't allowed in Java). As a result,
3910c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// protocols are referenced using angle brackets as follows:
3920c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
3930c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// id <NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
3940c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
395a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCProtocolDecl : public NamedDecl {
396980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// referenced protocols
397a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl **ReferencedProtocols;  // Null if none
398c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian  unsigned NumReferencedProtocols;  // 0 if none
399980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
400980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// protocol instance methods
401a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl **InstanceMethods;  // Null if not defined
4027ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumInstanceMethods;  // -1 if not defined
403980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
404980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// protocol class methods
405a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl **ClassMethods;  // Null if not defined
4067ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumClassMethods;  // -1 if not defined
407980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
408980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  bool isForwardProtoDecl; // declared with @protocol.
409423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff
410423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation EndLoc; // marks the '>' or identifier.
411423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation AtEndLoc; // marks the end of the entire interface.
412980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffpublic:
413a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl(SourceLocation L, unsigned numRefProtos,
414980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff                   IdentifierInfo *Id, bool FD = false)
415a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    : NamedDecl(ObjCProtocol, L, Id),
416c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian      ReferencedProtocols(0), NumReferencedProtocols(0),
4177ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      InstanceMethods(0), NumInstanceMethods(-1),
4187ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      ClassMethods(0), NumClassMethods(-1),
419980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      isForwardProtoDecl(FD) {
420980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff        AllocReferencedProtocols(numRefProtos);
421980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      }
422980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void AllocReferencedProtocols(unsigned numRefProtos) {
423980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    if (numRefProtos) {
424a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ReferencedProtocols = new ObjCProtocolDecl*[numRefProtos];
425980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      memset(ReferencedProtocols, '\0',
426a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek             numRefProtos*sizeof(ObjCProtocolDecl*));
427980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      NumReferencedProtocols = numRefProtos;
428980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    }
429980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
430a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
431a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                  ObjCMethodDecl **clsMethods, unsigned numClsMembers,
43260fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff                  SourceLocation AtEndLoc);
433980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
434a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setReferencedProtocols(unsigned idx, ObjCProtocolDecl *OID) {
435980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    assert((idx < NumReferencedProtocols) && "index out of range");
436980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    ReferencedProtocols[idx] = OID;
437980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
438980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
439a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl** getReferencedProtocols() const {
440980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    return ReferencedProtocols;
441980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
442c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian  unsigned getNumReferencedProtocols() const { return NumReferencedProtocols; }
4437ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumInstanceMethods() const { return NumInstanceMethods; }
4447ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumClassMethods() const { return NumClassMethods; }
44558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
446a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef ObjCMethodDecl * const * instmeth_iterator;
44758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  instmeth_iterator instmeth_begin() const { return InstanceMethods; }
44858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  instmeth_iterator instmeth_end() const {
44958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    return InstanceMethods+(NumInstanceMethods == -1 ? 0 : NumInstanceMethods);
45058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
45158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
452a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef ObjCMethodDecl * const * classmeth_iterator;
45358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  classmeth_iterator classmeth_begin() const { return ClassMethods; }
45458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  classmeth_iterator classmeth_end() const {
45558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    return ClassMethods+(NumClassMethods == -1 ? 0 : NumClassMethods);
45658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
45758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
45858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Get the local instance method declared in this interface.
459a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getInstanceMethod(Selector &Sel) {
46058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    for (instmeth_iterator I = instmeth_begin(), E = instmeth_end();
46158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff	     I != E; ++I) {
46258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff      if ((*I)->getSelector() == Sel)
46358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff        return *I;
46458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    }
46558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff	return 0;
46658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
46758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Get the local class method declared in this interface.
468a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getClassMethod(Selector &Sel) {
46958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
47058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff	     I != E; ++I) {
47158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff      if ((*I)->getSelector() == Sel)
47258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff        return *I;
47358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    }
47458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff	return 0;
47558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
476980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
47794a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // Lookup a method. First, we search locally. If a method isn't
47894a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // found, we search referenced protocols and class categories.
479a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *lookupInstanceMethod(Selector Sel);
480a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *lookupClassMethod(Selector Sel);
4817dd82836dca87cf828ce994f161b53a34f6cdb7eFariborz Jahanian
482768f26ee5892cd63ff0335a15d71a2385ba7c5eaSteve Naroff  bool isForwardDecl() const { return isForwardProtoDecl; }
483768f26ee5892cd63ff0335a15d71a2385ba7c5eaSteve Naroff  void setForwardDecl(bool val) { isForwardProtoDecl = val; }
484980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
485423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  // Location information, modeled after the Stmt API.
486423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getLocStart() const { return getLocation(); } // '@'protocol
487423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
488423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
489423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff
490423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  // We also need to record the @end location.
491423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getAtEndLoc() const { return AtEndLoc; }
492423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff
493a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCProtocol; }
494a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCProtocolDecl *D) { return true; }
495980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
496980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
497a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCClassDecl - Specifies a list of forward class declarations. For example:
49806ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff///
49906ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff/// @class NSCursor, NSImage, NSPasteboard, NSWindow;
5000c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
501a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCClassDecl : public Decl {
502a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl **ForwardDecls;
5037e620729fcb5a0042107f999dcf524f7357ce819Chris Lattner  unsigned NumForwardDecls;
50406ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroffpublic:
505a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCClassDecl(SourceLocation L, ObjCInterfaceDecl **Elts, unsigned nElts)
506a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    : Decl(ObjCClass, L) {
50706ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff    if (nElts) {
508a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ForwardDecls = new ObjCInterfaceDecl*[nElts];
509a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      memcpy(ForwardDecls, Elts, nElts*sizeof(ObjCInterfaceDecl*));
5107e620729fcb5a0042107f999dcf524f7357ce819Chris Lattner    } else {
5117e620729fcb5a0042107f999dcf524f7357ce819Chris Lattner      ForwardDecls = 0;
51206ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff    }
51306ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff    NumForwardDecls = nElts;
51406ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  }
515a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setInterfaceDecl(unsigned idx, ObjCInterfaceDecl *OID) {
5167e620729fcb5a0042107f999dcf524f7357ce819Chris Lattner    assert(idx < NumForwardDecls && "index out of range");
51706ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff    ForwardDecls[idx] = OID;
51806ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  }
519a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl** getForwardDecls() const { return ForwardDecls; }
5207e15891fc89256fc013bd1003676ad3197b85c25Steve Naroff  int getNumForwardDecls() const { return NumForwardDecls; }
5217e15891fc89256fc013bd1003676ad3197b85c25Steve Naroff
522a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCClass; }
523a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCClassDecl *D) { return true; }
52406ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff};
52506ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff
526a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations.
52706ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff/// For example:
52806ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff///
5290c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo;
5300c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
531a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCForwardProtocolDecl : public Decl {
532a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl **ReferencedProtocols;
5339fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner  unsigned NumReferencedProtocols;
53406ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroffpublic:
535a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCForwardProtocolDecl(SourceLocation L,
536a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                          ObjCProtocolDecl **Elts, unsigned nElts)
537a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  : Decl(ObjCForwardProtocol, L) {
538b97de3eddf0a0f7ff97204e7def6b7e0aa8953f2Chris Lattner    NumReferencedProtocols = nElts;
53906ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff    if (nElts) {
540a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ReferencedProtocols = new ObjCProtocolDecl*[nElts];
541a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      memcpy(ReferencedProtocols, Elts, nElts*sizeof(ObjCProtocolDecl*));
5429fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    } else {
5439fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner      ReferencedProtocols = 0;
544980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    }
54506ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  }
546a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setForwardProtocolDecl(unsigned idx, ObjCProtocolDecl *OID) {
5479fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    assert(idx < NumReferencedProtocols && "index out of range");
5487ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    ReferencedProtocols[idx] = OID;
54906ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  }
5509fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner
5519fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner  unsigned getNumForwardDecls() const { return NumReferencedProtocols; }
5529fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner
553a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl *getForwardProtocolDecl(unsigned idx) {
5549fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    assert(idx < NumReferencedProtocols && "index out of range");
5559fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    return ReferencedProtocols[idx];
5569fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner  }
557a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  const ObjCProtocolDecl *getForwardProtocolDecl(unsigned idx) const {
5589fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    assert(idx < NumReferencedProtocols && "index out of range");
5599fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    return ReferencedProtocols[idx];
5609fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner  }
5619fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner
56206ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  static bool classof(const Decl *D) {
563a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    return D->getKind() == ObjCForwardProtocol;
56406ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  }
565a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCForwardProtocolDecl *D) { return true; }
566980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
567980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
568a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCCategoryDecl - Represents a category declaration. A category allows
5690c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// you to add methods to an existing class (without subclassing or modifying
5700c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// the original class interface or implementation:-). Categories don't allow
5710c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// you to add instance data. The following example adds "myMethod" to all
5720c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// NSView's within a process:
5730c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
5740c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @interface NSView (MyViewMethods)
5750c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - myMethod;
5760c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @end
5770c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
5780c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Cateogries also allow you to split the implementation of a class across
5790c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// several files (a feature more naturally supported in C++).
5800c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
5810c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Categories were originally inspired by dynamic languages such as Common
5820c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Lisp and Smalltalk. More traditional class-based languages (C++, Java)
5830c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// don't support this level of dynamism, which is both powerful and dangerous.
5840c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
585a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCCategoryDecl : public NamedDecl {
586980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Interface belonging to this category
587a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *ClassInterface;
588980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
589980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// referenced protocols in this category
590a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl **ReferencedProtocols;  // Null if none
591c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian  unsigned NumReferencedProtocols;  // 0 if none
592980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
593980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// category instance methods
594a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl **InstanceMethods;  // Null if not defined
5957ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumInstanceMethods;  // -1 if not defined
596980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
597980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// category class methods
598a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl **ClassMethods;  // Null if not defined
5997ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumClassMethods;  // -1 if not defined
600980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
601980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Next category belonging to this class
602a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryDecl *NextClassCategory;
603ca3adf7e8cac8c9fbaf592b1e5c2be6f082de7baFariborz Jahanian
604423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation EndLoc; // marks the '>' or identifier.
605423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation AtEndLoc; // marks the end of the entire interface.
606980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffpublic:
607a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryDecl(SourceLocation L, unsigned numRefProtocol,IdentifierInfo *Id)
608a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    : NamedDecl(ObjCCategory, L, Id),
609c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian      ClassInterface(0), ReferencedProtocols(0), NumReferencedProtocols(0),
6107ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      InstanceMethods(0), NumInstanceMethods(-1),
6117ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      ClassMethods(0), NumClassMethods(-1),
612e5ab7f31054e87ee812830480a828a762cd9eb73Chris Lattner      NextClassCategory(0) {
613980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff        if (numRefProtocol) {
614a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek          ReferencedProtocols = new ObjCProtocolDecl*[numRefProtocol];
6157ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian          memset(ReferencedProtocols, '\0',
616a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                 numRefProtocol*sizeof(ObjCProtocolDecl*));
6177ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian          NumReferencedProtocols = numRefProtocol;
618980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff        }
619980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      }
620980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
621a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
622a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; }
623980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
624a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setCatReferencedProtocols(unsigned idx, ObjCProtocolDecl *OID) {
6257ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    assert((idx < NumReferencedProtocols) && "index out of range");
6267ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    ReferencedProtocols[idx] = OID;
627980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
628980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
629a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl **getReferencedProtocols() const {
6307ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    return ReferencedProtocols;
6318f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian  }
632c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian  unsigned getNumReferencedProtocols() const { return NumReferencedProtocols; }
6337ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumInstanceMethods() const { return NumInstanceMethods; }
6347ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumClassMethods() const { return NumClassMethods; }
63558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
636a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef ObjCMethodDecl * const * instmeth_iterator;
63758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  instmeth_iterator instmeth_begin() const { return InstanceMethods; }
63858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  instmeth_iterator instmeth_end() const {
63958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    return InstanceMethods+(NumInstanceMethods == -1 ? 0 : NumInstanceMethods);
64058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
64158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
642a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef ObjCMethodDecl * const * classmeth_iterator;
64358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  classmeth_iterator classmeth_begin() const { return ClassMethods; }
64458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  classmeth_iterator classmeth_end() const {
64558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    return ClassMethods+(NumClassMethods == -1 ? 0 : NumClassMethods);
64658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
64758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
64858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Get the local instance method declared in this interface.
649a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getInstanceMethod(Selector &Sel) {
65058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    for (instmeth_iterator I = instmeth_begin(), E = instmeth_end();
65158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff	     I != E; ++I) {
65258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff      if ((*I)->getSelector() == Sel)
65358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff        return *I;
65458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    }
65558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff	return 0;
65658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
65758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Get the local class method declared in this interface.
658a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getClassMethod(Selector &Sel) {
65958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
66058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff	     I != E; ++I) {
66158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff      if ((*I)->getSelector() == Sel)
66258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff        return *I;
66358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    }
66458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff	return 0;
66558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
6668f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
667a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
668a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                  ObjCMethodDecl **clsMethods, unsigned numClsMembers,
66960fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff                  SourceLocation AtEndLoc);
670980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
671a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
672980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void insertNextClassCategory() {
6733d58138992b9bc7b34aaa680f3ddf3971292eb7dSteve Naroff    NextClassCategory = ClassInterface->getCategoryList();
6743d58138992b9bc7b34aaa680f3ddf3971292eb7dSteve Naroff    ClassInterface->setCategoryList(this);
675980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
676423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  // Location information, modeled after the Stmt API.
677423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getLocStart() const { return getLocation(); } // '@'interface
678423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
679423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
680423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff
681423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  // We also need to record the @end location.
682423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getAtEndLoc() const { return AtEndLoc; }
683ca3adf7e8cac8c9fbaf592b1e5c2be6f082de7baFariborz Jahanian
684a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; }
685a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCCategoryDecl *D) { return true; }
686980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
6870c6b6243d3efd958c17943130e2a773653511edcSteve Naroff
688a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCCategoryImplDecl - An object of this class encapsulates a category
6898f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian/// @implementation declaration.
690a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCCategoryImplDecl : public NamedDecl {
6918f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian  /// Class interface for this category implementation
692a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *ClassInterface;
6938f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
694e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  /// implemented instance methods
695a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  llvm::SmallVector<ObjCMethodDecl*, 32> InstanceMethods;
6968f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
697e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  /// implemented class methods
698a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods;
699e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff
700e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  SourceLocation EndLoc;
701e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroffpublic:
702a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryImplDecl(SourceLocation L, IdentifierInfo *Id,
703a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                       ObjCInterfaceDecl *classInterface)
704a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    : NamedDecl(ObjCCategoryImpl, L, Id), ClassInterface(classInterface) {}
7058f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
706a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
7078f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
708ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  unsigned getNumInstanceMethods() const { return InstanceMethods.size(); }
709ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  unsigned getNumClassMethods() const { return ClassMethods.size(); }
710e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff
711a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void addInstanceMethod(ObjCMethodDecl *method) {
712e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff    InstanceMethods.push_back(method);
713e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  }
714a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void addClassMethod(ObjCMethodDecl *method) {
715e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff    ClassMethods.push_back(method);
716e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  }
71794a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // Get the instance method definition for this implementation.
718a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getInstanceMethod(Selector Sel);
71994a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff
72094a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // Get the class method definition for this implementation.
721a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getClassMethod(Selector Sel);
722e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff
723a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
724ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner    instmeth_iterator;
725ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
726ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  instmeth_iterator instmeth_end() const { return InstanceMethods.end(); }
727ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner
728a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
729ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner    classmeth_iterator;
730ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); }
731ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  classmeth_iterator classmeth_end() const { return ClassMethods.end(); }
732ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner
733ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner
734e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  // Location information, modeled after the Stmt API.
735e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  SourceLocation getLocStart() const { return getLocation(); }
736e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
737e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
738e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff
739a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;}
740a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCCategoryImplDecl *D) { return true; }
7418f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian};
7428f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
743a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCImplementationDecl - Represents a class definition - this is where
7440c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// method definitions are specified. For example:
7450c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
7460c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @implementation MyClass
7470c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - (void)myMethod { /* do something */ }
7480c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @end
7490c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
7500c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Typically, instance variables are specified in the class interface,
7510c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// *not* in the implemenentation. Nevertheless (for legacy reasons), we
7520c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// allow instance variables to be specified in the implementation. When
7530c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// specified, they need to be *identical* to the interface. Now that we
7540c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// have support for non-fragile ivars in ObjC 2.0, we can consider removing
7550c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// the legacy semantics and allow developers to move private ivar declarations
7560c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// from the class interface to the class implementation (but I digress:-)
7570c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
758a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCImplementationDecl : public NamedDecl {
759f4d331dd922f92478ebf30e808c0ca97ce49418bFariborz Jahanian  /// Class interface for this category implementation
760a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *ClassInterface;
761f4d331dd922f92478ebf30e808c0ca97ce49418bFariborz Jahanian
762980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Implementation Class's super class.
763a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *SuperClass;
764980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
765980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Optional Ivars/NumIvars - This is a new[]'d array of pointers to Decls.
766a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCIvarDecl **Ivars;   // Null if not specified
767980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  int NumIvars;   // -1 if not defined.
7680416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff
769980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// implemented instance methods
770a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  llvm::SmallVector<ObjCMethodDecl*, 32> InstanceMethods;
7710416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff
772980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// implemented class methods
773a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods;
7740416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff
7750416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  SourceLocation EndLoc;
7769fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattnerpublic:
777a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCImplementationDecl(SourceLocation L, IdentifierInfo *Id,
778a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                         ObjCInterfaceDecl *classInterface,
779a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                         ObjCInterfaceDecl *superDecl)
780a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    : NamedDecl(ObjCImplementation, L, Id),
7810416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff      ClassInterface(classInterface), SuperClass(superDecl),
7820416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff      Ivars(0), NumIvars(-1) {}
783980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
784a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void ObjCAddInstanceVariablesToClassImpl(ObjCIvarDecl **ivars,
785980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff                                           unsigned numIvars);
786980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
787a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void addInstanceMethod(ObjCMethodDecl *method) {
7880416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff    InstanceMethods.push_back(method);
7890416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  }
790a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void addClassMethod(ObjCMethodDecl *method) {
7910416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff    ClassMethods.push_back(method);
7920416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  }
7930416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  // Location information, modeled after the Stmt API.
7940416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  SourceLocation getLocStart() const { return getLocation(); }
7950416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
7960416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
7970416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff
798a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
799a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
800980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
801a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setSuperClass(ObjCInterfaceDecl * superCls)
802980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff         { SuperClass = superCls; }
803980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
80449747fdd0a05dfc1f15910267d6f86dfe83e6fc8Steve Naroff  int getNumInstanceMethods() const { return InstanceMethods.size(); }
80549747fdd0a05dfc1f15910267d6f86dfe83e6fc8Steve Naroff  int getNumClassMethods() const { return ClassMethods.size(); }
806c43d868355374d48296ad3be2c9c536698a5e9a8Steve Naroff
80749747fdd0a05dfc1f15910267d6f86dfe83e6fc8Steve Naroff  int getImplDeclNumIvars() const { return NumIvars; }
8080157c5144513438bb74aebf50d18f95df4104acbChris Lattner
8090157c5144513438bb74aebf50d18f95df4104acbChris Lattner
810a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
8110157c5144513438bb74aebf50d18f95df4104acbChris Lattner       instmeth_iterator;
8120157c5144513438bb74aebf50d18f95df4104acbChris Lattner  instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
8130157c5144513438bb74aebf50d18f95df4104acbChris Lattner  instmeth_iterator instmeth_end() const { return InstanceMethods.end(); }
8140157c5144513438bb74aebf50d18f95df4104acbChris Lattner
815a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
8160157c5144513438bb74aebf50d18f95df4104acbChris Lattner    classmeth_iterator;
8170157c5144513438bb74aebf50d18f95df4104acbChris Lattner  classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); }
8180157c5144513438bb74aebf50d18f95df4104acbChris Lattner  classmeth_iterator classmeth_end() const { return ClassMethods.end(); }
8190157c5144513438bb74aebf50d18f95df4104acbChris Lattner
82094a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // Get the instance method definition for this implementation.
821a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getInstanceMethod(Selector Sel);
8220157c5144513438bb74aebf50d18f95df4104acbChris Lattner
82394a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // Get the class method definition for this implementation.
824a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getClassMethod(Selector Sel);
8250157c5144513438bb74aebf50d18f95df4104acbChris Lattner
826a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef ObjCIvarDecl * const *ivar_iterator;
8270157c5144513438bb74aebf50d18f95df4104acbChris Lattner  ivar_iterator ivar_begin() const { return Ivars; }
82823c3bb768fd3eb24ff1a7402856405129afac0e3Chris Lattner  ivar_iterator ivar_end() const {return Ivars+(NumIvars == -1 ? 0 : NumIvars);}
8290157c5144513438bb74aebf50d18f95df4104acbChris Lattner
830980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  static bool classof(const Decl *D) {
831a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    return D->getKind() == ObjCImplementation;
832980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
833a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCImplementationDecl *D) { return true; }
834980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
835243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian
836a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
837243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian/// declared as @compatibility_alias alias class.
838a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCCompatibleAliasDecl : public ScopedDecl {
839243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  /// Class that this is an alias of.
840a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *AliasedClass;
841243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian
842243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanianpublic:
843a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCompatibleAliasDecl(SourceLocation L, IdentifierInfo *Id,
844a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                         ObjCInterfaceDecl* aliasedClass)
845243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  : ScopedDecl(CompatibleAlias, L, Id, 0),
846243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  AliasedClass(aliasedClass) {}
847243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian
848a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
849980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
850243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  static bool classof(const Decl *D) {
851243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian    return D->getKind() == CompatibleAlias;
852243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  }
853a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCCompatibleAliasDecl *D) { return true; }
854243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian
855243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian};
85682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
857a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCPropertyDecl : public Decl {
85882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanianpublic:
859564576b225386cbff375351597dd5e2a92872d38Fariborz Jahanian  enum PropertyAttributeKind { OBJC_PR_noattr = 0x0,
86082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_readonly = 0x01,
86182a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_getter = 0x02,
86282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_assign = 0x04,
86382a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_readwrite = 0x08,
86482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_retain = 0x10,
86582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_copy = 0x20,
86682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_nonatomic = 0x40,
86782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_setter = 0x80 };
86882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanianprivate:
86982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  // List of property name declarations
87082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  // FIXME: Property is not an ivar.
871a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCIvarDecl **PropertyDecls;
87282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  int NumPropertyDecls;
87382a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
874564576b225386cbff375351597dd5e2a92872d38Fariborz Jahanian  PropertyAttributeKind PropertyAttributes : 8;
87582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
87682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  IdentifierInfo *GetterName;    // getter name of NULL if no getter
87782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  IdentifierInfo *SetterName;    // setter name of NULL if no setter
87882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
87982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanianpublic:
880a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCPropertyDecl(SourceLocation L)
88182a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  : Decl(PropertyDecl, L),
88282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  PropertyDecls(0), NumPropertyDecls(-1), PropertyAttributes(OBJC_PR_noattr),
88382a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  GetterName(0), SetterName(0) {}
88482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
885a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCIvarDecl **const getPropertyDecls() const { return PropertyDecls; }
886a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setPropertyDecls(ObjCIvarDecl **property) { PropertyDecls = property; }
88782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
88882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  const int getNumPropertyDecls() const { return NumPropertyDecls; }
88982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  void setNumPropertyDecls(int num) { NumPropertyDecls = num; }
89082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
891564576b225386cbff375351597dd5e2a92872d38Fariborz Jahanian  const PropertyAttributeKind getPropertyAttributes() const
89282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian    { return PropertyAttributes; }
893564576b225386cbff375351597dd5e2a92872d38Fariborz Jahanian  void setPropertyAttributes(PropertyAttributeKind PRVal) {
89482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian    PropertyAttributes =
895564576b225386cbff375351597dd5e2a92872d38Fariborz Jahanian    (PropertyAttributeKind) (PropertyAttributes | PRVal);
89682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  }
89782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
89882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  const IdentifierInfo *getGetterName() const { return GetterName; }
89982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  IdentifierInfo *getGetterName() { return GetterName; }
90082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  void setGetterName(IdentifierInfo *Id) { GetterName = Id; }
90182a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
90282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  const IdentifierInfo *getSetterName() const { return SetterName; }
90382a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  IdentifierInfo *getSetterName() { return SetterName; }
90482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  void setSetterName(IdentifierInfo *Id) { SetterName = Id; }
90582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
90682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  static bool classof(const Decl *D) {
90782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian    return D->getKind() == PropertyDecl;
90882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  }
909a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCPropertyDecl *D) { return true; }
91082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian};
911980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
912980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff}  // end namespace clang
913980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff#endif
914