DeclObjC.h revision cca59d77c4b84fd2da268018dbaf9431a621e75b
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
61ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
6258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// @required/@optional
63ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  unsigned DeclImplementation : 2;
6458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
65ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
6658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// in, inout, etc.
67ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  unsigned objcDeclQualifier : 6;
6858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
6958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Context this method is declared in.
7058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  NamedDecl *MethodContext;
7158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
7258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // A unigue name for this method.
7358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  Selector SelName;
7458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
7558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Type of this method.
7658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  QualType MethodDeclType;
7758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
7858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// parameters of this Method.  This is null if there are no formals.
7958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  ParmVarDecl **ParamInfo;
8058cce3b0dcbdcc95b7e713795834b4cb2c8a008aChris Lattner  unsigned NumMethodParams;
8158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
8258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// List of attributes for this method declaration.
8358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  AttributeList *MethodAttrs;
8458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
8558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  SourceLocation EndLoc; // the location of the ';' or '{'.
8658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
8758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // The following are only used for method definitions, null otherwise.
8858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // FIXME: space savings opportunity, consider a sub-class.
8958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  Stmt *Body;
9058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  ParmVarDecl *SelfDecl;
916c4ae5de0c356777446f823b573821fb95560d91Chris Lattner
92a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
9358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff                 Selector SelInfo, QualType T,
9458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff                 Decl *contextDecl,
9558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff                 AttributeList *M = 0, bool isInstance = true,
9658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff                 bool isVariadic = false,
9758cce3b0dcbdcc95b7e713795834b4cb2c8a008aChris Lattner                 ImplementationControl impControl = None)
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),
103b06fa3b86951b9f179c99c3768331536c32e902dChris Lattner    ParamInfo(0), NumMethodParams(0),
10458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    MethodAttrs(M), EndLoc(endLoc), Body(0), SelfDecl(0) {}
105b06fa3b86951b9f179c99c3768331536c32e902dChris Lattner  virtual ~ObjCMethodDecl();
1066c4ae5de0c356777446f823b573821fb95560d91Chris Lattnerpublic:
1076c4ae5de0c356777446f823b573821fb95560d91Chris Lattner
1086c4ae5de0c356777446f823b573821fb95560d91Chris Lattner  static ObjCMethodDecl *Create(ASTContext &C, SourceLocation beginLoc,
1096c4ae5de0c356777446f823b573821fb95560d91Chris Lattner                                SourceLocation endLoc, Selector SelInfo,
1106c4ae5de0c356777446f823b573821fb95560d91Chris Lattner                                QualType T, Decl *contextDecl,
1116c4ae5de0c356777446f823b573821fb95560d91Chris Lattner                                AttributeList *M = 0, bool isInstance = true,
1126c4ae5de0c356777446f823b573821fb95560d91Chris Lattner                                bool isVariadic = false,
113b06fa3b86951b9f179c99c3768331536c32e902dChris Lattner                                ImplementationControl impControl = None);
11458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
115ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  ObjCDeclQualifier getObjCDeclQualifier() const {
116ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek    return ObjCDeclQualifier(objcDeclQualifier);
117ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  }
118a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
11958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
12058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Location information, modeled after the Stmt API.
12158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  SourceLocation getLocStart() const { return getLocation(); }
12258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
12358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
12458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  NamedDecl *getMethodContext() const { return MethodContext; }
12558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
126a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *const getClassInterface() const;
12758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
12858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  Selector getSelector() const { return SelName; }
129faf5e779d16bb4590f2a97e1c7ded255eddd90f3Fariborz Jahanian  unsigned getSynthesizedMethodSize() const;
13058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  QualType getResultType() const { return MethodDeclType; }
13158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
132d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  // Iterator access to formal parameters.
13358cce3b0dcbdcc95b7e713795834b4cb2c8a008aChris Lattner  unsigned param_size() const { return NumMethodParams; }
134d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  typedef ParmVarDecl **param_iterator;
135d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  typedef ParmVarDecl * const *param_const_iterator;
136d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  param_iterator param_begin() { return ParamInfo; }
137d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  param_iterator param_end() { return ParamInfo+param_size(); }
138d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  param_const_iterator param_begin() const { return ParamInfo; }
139d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  param_const_iterator param_end() const { return ParamInfo+param_size(); }
140d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner
14158cce3b0dcbdcc95b7e713795834b4cb2c8a008aChris Lattner  unsigned getNumParams() const { return NumMethodParams; }
14258cce3b0dcbdcc95b7e713795834b4cb2c8a008aChris Lattner  ParmVarDecl *getParamDecl(unsigned i) const {
14358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    assert(i < getNumParams() && "Illegal param #");
14458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    return ParamInfo[i];
14558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
1462338d58a905191c4205d4f73affd0bdaa13493b4Fariborz Jahanian  void setParamDecl(int i, ParmVarDecl *pDecl) {
1472338d58a905191c4205d4f73affd0bdaa13493b4Fariborz Jahanian    ParamInfo[i] = pDecl;
1482338d58a905191c4205d4f73affd0bdaa13493b4Fariborz Jahanian  }
14958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  void setMethodParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
15058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
15158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  AttributeList *getMethodAttrs() const {return MethodAttrs;}
15258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  bool isInstance() const { return IsInstance; }
15358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  bool isVariadic() const { return IsVariadic; }
15458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
15558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Related to protocols declared in  @protocol
15658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  void setDeclImplementation(ImplementationControl ic) {
15758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    DeclImplementation = ic;
15858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
15958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  ImplementationControl getImplementationControl() const {
160ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek    return ImplementationControl(DeclImplementation);
16158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
16258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  Stmt *const getBody() const { return Body; }
16358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  void setBody(Stmt *B) { Body = B; }
16458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
16558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  ParmVarDecl *const getSelfDecl() const { return SelfDecl; }
16658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  void setSelfDecl(ParmVarDecl *PVD) { SelfDecl = PVD; }
16758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
16858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Implement isa/cast/dyncast/etc.
169a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCMethod; }
170a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCMethodDecl *D) { return true; }
17158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff};
172b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian
173a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCInterfaceDecl - Represents an ObjC class declaration. For example:
1740c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
1750c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   // MostPrimitive declares no super class (not particularly useful).
1760c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @interface MostPrimitive
1770c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     // no instance variables or methods.
1780c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @end
1790c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
180fd5de471478a507dd2495c4ea9bcab801ea5fa65Chris Lattner///   // NSResponder inherits from NSObject & implements NSCoding (a protocol).
1810c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @interface NSResponder : NSObject <NSCoding>
182a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek///   { // instance variables are represented by ObjCIvarDecl.
1830c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id nextResponder; // nextResponder instance variable.
1840c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   }
1850c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   - (NSResponder *)nextResponder; // return a pointer to NSResponder.
1860c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
1870c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @end                                    // to an NSEvent.
1880c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
1890c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   Unlike C/C++, forward class declarations are accomplished with @class.
1900c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   Unlike C/C++, @class allows for a list of classes to be forward declared.
1910c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
1920c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   typically inherit from NSObject (an exception is NSProxy).
1930c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
194a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCInterfaceDecl : public TypeDecl {
195980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
196980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Class's super class.
197a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *SuperClass;
198980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
199980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Protocols referenced in interface header declaration
200a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl **ReferencedProtocols;  // Null if none
201c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian  unsigned NumReferencedProtocols;  // 0 if none
202980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
203980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Ivars/NumIvars - This is a new[]'d array of pointers to Decls.
204a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCIvarDecl **Ivars;   // Null if not defined.
205980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  int NumIvars;   // -1 if not defined.
206980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
207980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// instance methods
208a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl **InstanceMethods;  // Null if not defined
2097ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumInstanceMethods;  // -1 if not defined
210980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
211980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// class methods
212a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl **ClassMethods;  // Null if not defined
2137ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumClassMethods;  // -1 if not defined
214980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
215980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// List of categories defined for this class.
216a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryDecl *CategoryList;
21782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
21882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  /// class properties
219a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCPropertyDecl **PropertyDecl;  // Null if no property
22082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  int NumPropertyDecl;  // -1 if no property
221980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
2223a3ca1b35a7121aea0bf465a192dce748465e10fFariborz Jahanian  bool ForwardDecl:1; // declared with @class.
2233a3ca1b35a7121aea0bf465a192dce748465e10fFariborz Jahanian  bool InternalInterface:1; // true - no @interface for @implementation
22460fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff
225f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  SourceLocation EndLoc; // marks the '>', '}', or identifier.
226f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  SourceLocation AtEndLoc; // marks the end of the entire interface.
2270e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner
228a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl(SourceLocation atLoc, unsigned numRefProtos,
229cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner                    IdentifierInfo *Id, bool FD, bool isInternal)
230a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    : TypeDecl(ObjCInterface, atLoc, Id, 0), SuperClass(0),
231c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian      ReferencedProtocols(0), NumReferencedProtocols(0), Ivars(0),
2327ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      NumIvars(-1),
2337ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      InstanceMethods(0), NumInstanceMethods(-1),
2347ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      ClassMethods(0), NumClassMethods(-1),
23582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian      CategoryList(0), PropertyDecl(0), NumPropertyDecl(-1),
23682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian      ForwardDecl(FD), InternalInterface(isInternal) {
237980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff        AllocIntfRefProtocols(numRefProtos);
238980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      }
2390e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattnerpublic:
2400e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner
2410e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner  static ObjCInterfaceDecl *Create(ASTContext &C, SourceLocation atLoc,
2420e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner                                   unsigned numRefProtos, IdentifierInfo *Id,
2430e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner                                   bool ForwardDecl = false,
2440e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner                                   bool isInternal = false);
245a5997c4f36e0f5aa44623a5b1e3b914760d1ec68Steve Naroff
246a5997c4f36e0f5aa44623a5b1e3b914760d1ec68Steve Naroff  // This is necessary when converting a forward declaration to a definition.
247980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void AllocIntfRefProtocols(unsigned numRefProtos) {
248980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    if (numRefProtos) {
249a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ReferencedProtocols = new ObjCProtocolDecl*[numRefProtos];
2507ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      memset(ReferencedProtocols, '\0',
251a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek             numRefProtos*sizeof(ObjCProtocolDecl*));
2527ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      NumReferencedProtocols = numRefProtos;
253980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    }
254980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
255980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
256a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl **getReferencedProtocols() const {
2577ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    return ReferencedProtocols;
2587ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  }
259c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian  unsigned getNumIntfRefProtocols() const { return NumReferencedProtocols; }
260980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
2610330071714f1ba09e926becd666f4fc0ed62bc0bSteve Naroff  int getNumInstanceVariables() const { return NumIvars; }
262980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
263a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef ObjCIvarDecl * const *ivar_iterator;
2645564e07af5e62875f3b83fc2e5a8823588b5adeaChris Lattner  unsigned ivar_size() const { return NumIvars == -1 ?0 : NumIvars; }
265be6df088d69bca0e99c7845a6cd8c1ca85034f31Chris Lattner  ivar_iterator ivar_begin() const { return Ivars; }
2665564e07af5e62875f3b83fc2e5a8823588b5adeaChris Lattner  ivar_iterator ivar_end() const { return Ivars + ivar_size();}
267be6df088d69bca0e99c7845a6cd8c1ca85034f31Chris Lattner
2687ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumInstanceMethods() const { return NumInstanceMethods; }
2697ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumClassMethods() const { return NumClassMethods; }
270980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
271a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef ObjCMethodDecl * const * instmeth_iterator;
2724c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  instmeth_iterator instmeth_begin() const { return InstanceMethods; }
2734c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  instmeth_iterator instmeth_end() const {
27423c3bb768fd3eb24ff1a7402856405129afac0e3Chris Lattner    return InstanceMethods+(NumInstanceMethods == -1 ? 0 : NumInstanceMethods);
2754c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  }
2764c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner
277a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef ObjCMethodDecl * const * classmeth_iterator;
2784c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  classmeth_iterator classmeth_begin() const { return ClassMethods; }
2794c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  classmeth_iterator classmeth_end() const {
28023c3bb768fd3eb24ff1a7402856405129afac0e3Chris Lattner    return ClassMethods+(NumClassMethods == -1 ? 0 : NumClassMethods);
2814c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  }
2824c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner
283a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void addInstanceVariablesToClass(ObjCIvarDecl **ivars, unsigned numIvars,
28460fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff                                   SourceLocation RBracLoc);
285980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
286a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
287a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                  ObjCMethodDecl **clsMethods, unsigned numClsMembers,
28860fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff                  SourceLocation AtEnd);
289980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
290768f26ee5892cd63ff0335a15d71a2385ba7c5eaSteve Naroff  bool isForwardDecl() const { return ForwardDecl; }
291768f26ee5892cd63ff0335a15d71a2385ba7c5eaSteve Naroff  void setForwardDecl(bool val) { ForwardDecl = val; }
292980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
293a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setIntfRefProtocols(unsigned idx, ObjCProtocolDecl *OID) {
2947ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    assert((idx < NumReferencedProtocols) && "index out of range");
2957ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    ReferencedProtocols[idx] = OID;
296980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
297980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
298a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
299a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
300980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
301a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryDecl* getCategoryList() const { return CategoryList; }
302a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setCategoryList(ObjCCategoryDecl *category) {
3033d58138992b9bc7b34aaa680f3ddf3971292eb7dSteve Naroff         CategoryList = category;
304980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
305a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *ivarName,
306a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                                       ObjCInterfaceDecl *&clsDeclared);
307c81c8144a661a49d7b9dae8d2080dee2e43186ecChris Lattner
30858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Get the local instance method declared in this interface.
309a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getInstanceMethod(Selector &Sel) {
31058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    for (instmeth_iterator I = instmeth_begin(), E = instmeth_end();
3110e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner         I != E; ++I) {
31258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff      if ((*I)->getSelector() == Sel)
31358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff        return *I;
31458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    }
3150e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner    return 0;
31658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
31758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Get the local class method declared in this interface.
318a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getClassMethod(Selector &Sel) {
31958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
3200e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner         I != E; ++I) {
32158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff      if ((*I)->getSelector() == Sel)
32258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff        return *I;
32358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    }
3240e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner    return 0;
32558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
32694a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // Lookup a method. First, we search locally. If a method isn't
32794a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // found, we search referenced protocols and class categories.
328a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *lookupInstanceMethod(Selector Sel);
329a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *lookupClassMethod(Selector Sel);
33060fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff
331f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  // Location information, modeled after the Stmt API.
33260fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff  SourceLocation getLocStart() const { return getLocation(); } // '@'interface
333f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
334f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
33560fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff
33660fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff  // We also need to record the @end location.
337f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  SourceLocation getAtEndLoc() const { return AtEndLoc; }
33882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
339ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  int getNumPropertyDecl() const { return NumPropertyDecl; }
34082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  void setNumPropertyDecl(int num) { NumPropertyDecl = num; }
34182a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
342a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCPropertyDecl **const getPropertyDecl() const { return PropertyDecl; }
343a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCPropertyDecl **getPropertyDecl() { return PropertyDecl; }
344a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setPropertyDecls(ObjCPropertyDecl **properties) {
34582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian    PropertyDecl = properties;
34682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  }
347f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff
3484b6df3fa953267c5d755628c8afd818bb571e579Fariborz Jahanian  /// ImplicitInterfaceDecl - check that this is an implicitely declared
349a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  /// ObjCInterfaceDecl node. This is for legacy objective-c @implementation
3504b6df3fa953267c5d755628c8afd818bb571e579Fariborz Jahanian  /// declaration without an @interface declaration.
3513a3ca1b35a7121aea0bf465a192dce748465e10fFariborz Jahanian  bool ImplicitInterfaceDecl() const { return InternalInterface; }
3524b6df3fa953267c5d755628c8afd818bb571e579Fariborz Jahanian
353a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCInterface; }
354a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCInterfaceDecl *D) { return true; }
355980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
356980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
357a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
3580c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// instance variables are identical to C. The only exception is Objective-C
3590c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// supports C++ style access control. For example:
3600c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
3610c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @interface IvarExample : NSObject
3620c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   {
3630c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id defaultToPrivate; // same as C++.
3640c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @public:
3650c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id canBePublic; // same as C++.
3660c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @protected:
3670c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id canBeProtected; // same as C++.
3680c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @package:
3690c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id canBePackage; // framework visibility (not available in C++).
3700c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   }
3710c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
372a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCIvarDecl : public FieldDecl {
373a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCIvarDecl(SourceLocation L, IdentifierInfo *Id, QualType T)
374a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    : FieldDecl(ObjCIvar, L, Id, T) {}
3750e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattnerpublic:
3760e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner  static ObjCIvarDecl *Create(ASTContext &C, SourceLocation L,
3770e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner                              IdentifierInfo *Id, QualType T);
378980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
379980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  enum AccessControl {
380980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    None, Private, Protected, Public, Package
381980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  };
382980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void setAccessControl(AccessControl ac) { DeclAccess = ac; }
383ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
384980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
385980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  // Implement isa/cast/dyncast/etc.
386a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCIvar; }
387a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCIvarDecl *D) { return true; }
388980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffprivate:
389ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
390ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  unsigned DeclAccess : 3;
391980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
392980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
393980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
394a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols
3950c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// declare a pure abstract type (i.e no instance variables are permitted).
3960c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Protocols orginally drew inspiration from C++ pure virtual functions (a C++
3970c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// feature with nice semantics and lousy syntax:-). Here is an example:
3980c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
3990c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @protocol NSDraggingInfo
4000c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - (NSWindow *)draggingDestinationWindow;
4010c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - (NSImage *)draggedImage;
4020c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @end
4030c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
4040c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @interface ImplementsNSDraggingInfo : NSObject <NSDraggingInfo>
4050c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @end
4060c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
407a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
4080c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// protocols are in distinct namespaces. For example, Cocoa defines both
4090c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// an NSObject protocol and class (which isn't allowed in Java). As a result,
4100c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// protocols are referenced using angle brackets as follows:
4110c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
4120c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// id <NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
4130c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
414a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCProtocolDecl : public NamedDecl {
415980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// referenced protocols
416a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl **ReferencedProtocols;  // Null if none
417c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian  unsigned NumReferencedProtocols;  // 0 if none
418980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
419980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// protocol instance methods
420a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl **InstanceMethods;  // Null if not defined
4217ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumInstanceMethods;  // -1 if not defined
422980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
423980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// protocol class methods
424a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl **ClassMethods;  // Null if not defined
4257ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumClassMethods;  // -1 if not defined
426980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
427980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  bool isForwardProtoDecl; // declared with @protocol.
428423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff
429423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation EndLoc; // marks the '>' or identifier.
430423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation AtEndLoc; // marks the end of the entire interface.
431cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner
432a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl(SourceLocation L, unsigned numRefProtos,
433cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner                   IdentifierInfo *Id, bool FD)
434a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    : NamedDecl(ObjCProtocol, L, Id),
435c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian      ReferencedProtocols(0), NumReferencedProtocols(0),
4367ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      InstanceMethods(0), NumInstanceMethods(-1),
4377ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      ClassMethods(0), NumClassMethods(-1),
438980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      isForwardProtoDecl(FD) {
439cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner    AllocReferencedProtocols(numRefProtos);
440cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner  }
441cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattnerpublic:
442cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner  static ObjCProtocolDecl *Create(ASTContext &C, SourceLocation L,
443cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner                                  unsigned numRefProtos, IdentifierInfo *Id,
444cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner                                  bool ForwardDecl = false);
445cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner
446980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void AllocReferencedProtocols(unsigned numRefProtos) {
447980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    if (numRefProtos) {
448a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ReferencedProtocols = new ObjCProtocolDecl*[numRefProtos];
449980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      memset(ReferencedProtocols, '\0',
450a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek             numRefProtos*sizeof(ObjCProtocolDecl*));
451980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      NumReferencedProtocols = numRefProtos;
452980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    }
453980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
454a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
455a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                  ObjCMethodDecl **clsMethods, unsigned numClsMembers,
45660fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff                  SourceLocation AtEndLoc);
457980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
458a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setReferencedProtocols(unsigned idx, ObjCProtocolDecl *OID) {
459980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    assert((idx < NumReferencedProtocols) && "index out of range");
460980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    ReferencedProtocols[idx] = OID;
461980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
462980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
463a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl** getReferencedProtocols() const {
464980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    return ReferencedProtocols;
465980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
466c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian  unsigned getNumReferencedProtocols() const { return NumReferencedProtocols; }
4677ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumInstanceMethods() const { return NumInstanceMethods; }
4687ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumClassMethods() const { return NumClassMethods; }
46958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
470a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef ObjCMethodDecl * const * instmeth_iterator;
47158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  instmeth_iterator instmeth_begin() const { return InstanceMethods; }
47258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  instmeth_iterator instmeth_end() const {
47358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    return InstanceMethods+(NumInstanceMethods == -1 ? 0 : NumInstanceMethods);
47458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
47558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
476a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef ObjCMethodDecl * const * classmeth_iterator;
47758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  classmeth_iterator classmeth_begin() const { return ClassMethods; }
47858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  classmeth_iterator classmeth_end() const {
47958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    return ClassMethods+(NumClassMethods == -1 ? 0 : NumClassMethods);
48058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
48158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
48258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Get the local instance method declared in this interface.
483a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getInstanceMethod(Selector &Sel) {
48458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    for (instmeth_iterator I = instmeth_begin(), E = instmeth_end();
485c81c8144a661a49d7b9dae8d2080dee2e43186ecChris Lattner             I != E; ++I) {
48658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff      if ((*I)->getSelector() == Sel)
48758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff        return *I;
48858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    }
489c81c8144a661a49d7b9dae8d2080dee2e43186ecChris Lattner        return 0;
49058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
49158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Get the local class method declared in this interface.
492a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getClassMethod(Selector &Sel) {
49358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
494c81c8144a661a49d7b9dae8d2080dee2e43186ecChris Lattner             I != E; ++I) {
49558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff      if ((*I)->getSelector() == Sel)
49658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff        return *I;
49758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    }
498c81c8144a661a49d7b9dae8d2080dee2e43186ecChris Lattner        return 0;
49958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
500980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
50194a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // Lookup a method. First, we search locally. If a method isn't
50294a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // found, we search referenced protocols and class categories.
503a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *lookupInstanceMethod(Selector Sel);
504a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *lookupClassMethod(Selector Sel);
5057dd82836dca87cf828ce994f161b53a34f6cdb7eFariborz Jahanian
506768f26ee5892cd63ff0335a15d71a2385ba7c5eaSteve Naroff  bool isForwardDecl() const { return isForwardProtoDecl; }
507768f26ee5892cd63ff0335a15d71a2385ba7c5eaSteve Naroff  void setForwardDecl(bool val) { isForwardProtoDecl = val; }
508980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
509423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  // Location information, modeled after the Stmt API.
510423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getLocStart() const { return getLocation(); } // '@'protocol
511423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
512423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
513423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff
514423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  // We also need to record the @end location.
515423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getAtEndLoc() const { return AtEndLoc; }
516423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff
517a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCProtocol; }
518a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCProtocolDecl *D) { return true; }
519980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
520980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
521a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCClassDecl - Specifies a list of forward class declarations. For example:
52206ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff///
52306ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff/// @class NSCursor, NSImage, NSPasteboard, NSWindow;
5240c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
525a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCClassDecl : public Decl {
526a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl **ForwardDecls;
5277e620729fcb5a0042107f999dcf524f7357ce819Chris Lattner  unsigned NumForwardDecls;
52806ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroffpublic:
529a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCClassDecl(SourceLocation L, ObjCInterfaceDecl **Elts, unsigned nElts)
530a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    : Decl(ObjCClass, L) {
53106ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff    if (nElts) {
532a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ForwardDecls = new ObjCInterfaceDecl*[nElts];
533a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      memcpy(ForwardDecls, Elts, nElts*sizeof(ObjCInterfaceDecl*));
5347e620729fcb5a0042107f999dcf524f7357ce819Chris Lattner    } else {
5357e620729fcb5a0042107f999dcf524f7357ce819Chris Lattner      ForwardDecls = 0;
53606ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff    }
53706ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff    NumForwardDecls = nElts;
53806ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  }
539a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setInterfaceDecl(unsigned idx, ObjCInterfaceDecl *OID) {
5407e620729fcb5a0042107f999dcf524f7357ce819Chris Lattner    assert(idx < NumForwardDecls && "index out of range");
54106ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff    ForwardDecls[idx] = OID;
54206ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  }
543a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl** getForwardDecls() const { return ForwardDecls; }
5447e15891fc89256fc013bd1003676ad3197b85c25Steve Naroff  int getNumForwardDecls() const { return NumForwardDecls; }
5457e15891fc89256fc013bd1003676ad3197b85c25Steve Naroff
546a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCClass; }
547a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCClassDecl *D) { return true; }
54806ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff};
54906ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff
550a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations.
55106ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff/// For example:
55206ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff///
5530c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo;
5540c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
555a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCForwardProtocolDecl : public Decl {
556a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl **ReferencedProtocols;
5579fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner  unsigned NumReferencedProtocols;
55806ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroffpublic:
559a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCForwardProtocolDecl(SourceLocation L,
560a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                          ObjCProtocolDecl **Elts, unsigned nElts)
561a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  : Decl(ObjCForwardProtocol, L) {
562b97de3eddf0a0f7ff97204e7def6b7e0aa8953f2Chris Lattner    NumReferencedProtocols = nElts;
56306ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff    if (nElts) {
564a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ReferencedProtocols = new ObjCProtocolDecl*[nElts];
565a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      memcpy(ReferencedProtocols, Elts, nElts*sizeof(ObjCProtocolDecl*));
5669fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    } else {
5679fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner      ReferencedProtocols = 0;
568980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    }
56906ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  }
570a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setForwardProtocolDecl(unsigned idx, ObjCProtocolDecl *OID) {
5719fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    assert(idx < NumReferencedProtocols && "index out of range");
5727ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    ReferencedProtocols[idx] = OID;
57306ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  }
5749fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner
5759fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner  unsigned getNumForwardDecls() const { return NumReferencedProtocols; }
5769fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner
577a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl *getForwardProtocolDecl(unsigned idx) {
5789fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    assert(idx < NumReferencedProtocols && "index out of range");
5799fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    return ReferencedProtocols[idx];
5809fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner  }
581a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  const ObjCProtocolDecl *getForwardProtocolDecl(unsigned idx) const {
5829fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    assert(idx < NumReferencedProtocols && "index out of range");
5839fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    return ReferencedProtocols[idx];
5849fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner  }
5859fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner
58606ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  static bool classof(const Decl *D) {
587a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    return D->getKind() == ObjCForwardProtocol;
58806ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  }
589a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCForwardProtocolDecl *D) { return true; }
590980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
591980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
592a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCCategoryDecl - Represents a category declaration. A category allows
5930c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// you to add methods to an existing class (without subclassing or modifying
5940c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// the original class interface or implementation:-). Categories don't allow
5950c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// you to add instance data. The following example adds "myMethod" to all
5960c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// NSView's within a process:
5970c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
5980c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @interface NSView (MyViewMethods)
5990c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - myMethod;
6000c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @end
6010c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
6020c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Cateogries also allow you to split the implementation of a class across
6030c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// several files (a feature more naturally supported in C++).
6040c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
6050c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Categories were originally inspired by dynamic languages such as Common
6060c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Lisp and Smalltalk. More traditional class-based languages (C++, Java)
6070c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// don't support this level of dynamism, which is both powerful and dangerous.
6080c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
609a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCCategoryDecl : public NamedDecl {
610980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Interface belonging to this category
611a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *ClassInterface;
612980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
613980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// referenced protocols in this category
614a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl **ReferencedProtocols;  // Null if none
615c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian  unsigned NumReferencedProtocols;  // 0 if none
616980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
617980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// category instance methods
618a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl **InstanceMethods;  // Null if not defined
6197ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumInstanceMethods;  // -1 if not defined
620980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
621980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// category class methods
622a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl **ClassMethods;  // Null if not defined
6237ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumClassMethods;  // -1 if not defined
624980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
625980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Next category belonging to this class
626a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryDecl *NextClassCategory;
627ca3adf7e8cac8c9fbaf592b1e5c2be6f082de7baFariborz Jahanian
628423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation EndLoc; // marks the '>' or identifier.
629423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation AtEndLoc; // marks the end of the entire interface.
630980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffpublic:
631a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryDecl(SourceLocation L, unsigned numRefProtocol,IdentifierInfo *Id)
632a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    : NamedDecl(ObjCCategory, L, Id),
633c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian      ClassInterface(0), ReferencedProtocols(0), NumReferencedProtocols(0),
6347ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      InstanceMethods(0), NumInstanceMethods(-1),
6357ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      ClassMethods(0), NumClassMethods(-1),
636e5ab7f31054e87ee812830480a828a762cd9eb73Chris Lattner      NextClassCategory(0) {
637980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff        if (numRefProtocol) {
638a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek          ReferencedProtocols = new ObjCProtocolDecl*[numRefProtocol];
6397ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian          memset(ReferencedProtocols, '\0',
640a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                 numRefProtocol*sizeof(ObjCProtocolDecl*));
6417ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian          NumReferencedProtocols = numRefProtocol;
642980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff        }
643980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      }
644980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
645a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
646a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; }
647980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
648a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setCatReferencedProtocols(unsigned idx, ObjCProtocolDecl *OID) {
6497ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    assert((idx < NumReferencedProtocols) && "index out of range");
6507ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    ReferencedProtocols[idx] = OID;
651980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
652980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
653a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl **getReferencedProtocols() const {
6547ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    return ReferencedProtocols;
6558f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian  }
656c395bda57a0b2f6d8433a462caa780a7dcb7307bFariborz Jahanian  unsigned getNumReferencedProtocols() const { return NumReferencedProtocols; }
6577ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumInstanceMethods() const { return NumInstanceMethods; }
6587ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumClassMethods() const { return NumClassMethods; }
65958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
660a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef ObjCMethodDecl * const * instmeth_iterator;
66158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  instmeth_iterator instmeth_begin() const { return InstanceMethods; }
66258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  instmeth_iterator instmeth_end() const {
66358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    return InstanceMethods+(NumInstanceMethods == -1 ? 0 : NumInstanceMethods);
66458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
66558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
666a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef ObjCMethodDecl * const * classmeth_iterator;
66758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  classmeth_iterator classmeth_begin() const { return ClassMethods; }
66858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  classmeth_iterator classmeth_end() const {
66958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    return ClassMethods+(NumClassMethods == -1 ? 0 : NumClassMethods);
67058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
67158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
67258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Get the local instance method declared in this interface.
673a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getInstanceMethod(Selector &Sel) {
67458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    for (instmeth_iterator I = instmeth_begin(), E = instmeth_end();
675c81c8144a661a49d7b9dae8d2080dee2e43186ecChris Lattner             I != E; ++I) {
67658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff      if ((*I)->getSelector() == Sel)
67758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff        return *I;
67858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    }
679c81c8144a661a49d7b9dae8d2080dee2e43186ecChris Lattner        return 0;
68058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
68158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Get the local class method declared in this interface.
682a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getClassMethod(Selector &Sel) {
68358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
684c81c8144a661a49d7b9dae8d2080dee2e43186ecChris Lattner             I != E; ++I) {
68558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff      if ((*I)->getSelector() == Sel)
68658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff        return *I;
68758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    }
688c81c8144a661a49d7b9dae8d2080dee2e43186ecChris Lattner        return 0;
68958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
6908f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
691a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
692a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                  ObjCMethodDecl **clsMethods, unsigned numClsMembers,
69360fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff                  SourceLocation AtEndLoc);
694980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
695a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
696980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void insertNextClassCategory() {
6973d58138992b9bc7b34aaa680f3ddf3971292eb7dSteve Naroff    NextClassCategory = ClassInterface->getCategoryList();
6983d58138992b9bc7b34aaa680f3ddf3971292eb7dSteve Naroff    ClassInterface->setCategoryList(this);
699980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
700423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  // Location information, modeled after the Stmt API.
701423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getLocStart() const { return getLocation(); } // '@'interface
702423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
703423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
704423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff
705423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  // We also need to record the @end location.
706423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getAtEndLoc() const { return AtEndLoc; }
707ca3adf7e8cac8c9fbaf592b1e5c2be6f082de7baFariborz Jahanian
708a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; }
709a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCCategoryDecl *D) { return true; }
710980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
7110c6b6243d3efd958c17943130e2a773653511edcSteve Naroff
712a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCCategoryImplDecl - An object of this class encapsulates a category
7138f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian/// @implementation declaration.
714a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCCategoryImplDecl : public NamedDecl {
7158f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian  /// Class interface for this category implementation
716a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *ClassInterface;
7178f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
718e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  /// implemented instance methods
719a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  llvm::SmallVector<ObjCMethodDecl*, 32> InstanceMethods;
7208f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
721e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  /// implemented class methods
722a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods;
723e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff
724e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  SourceLocation EndLoc;
725e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroffpublic:
726a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryImplDecl(SourceLocation L, IdentifierInfo *Id,
727a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                       ObjCInterfaceDecl *classInterface)
728a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    : NamedDecl(ObjCCategoryImpl, L, Id), ClassInterface(classInterface) {}
7298f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
730a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
7318f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
732ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  unsigned getNumInstanceMethods() const { return InstanceMethods.size(); }
733ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  unsigned getNumClassMethods() const { return ClassMethods.size(); }
734e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff
735a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void addInstanceMethod(ObjCMethodDecl *method) {
736e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff    InstanceMethods.push_back(method);
737e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  }
738a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void addClassMethod(ObjCMethodDecl *method) {
739e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff    ClassMethods.push_back(method);
740e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  }
74194a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // Get the instance method definition for this implementation.
742a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getInstanceMethod(Selector Sel);
74394a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff
74494a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // Get the class method definition for this implementation.
745a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getClassMethod(Selector Sel);
746e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff
747a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
748ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner    instmeth_iterator;
749ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
750ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  instmeth_iterator instmeth_end() const { return InstanceMethods.end(); }
751ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner
752a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
753ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner    classmeth_iterator;
754ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); }
755ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  classmeth_iterator classmeth_end() const { return ClassMethods.end(); }
756ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner
757ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner
758e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  // Location information, modeled after the Stmt API.
759e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  SourceLocation getLocStart() const { return getLocation(); }
760e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
761e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
762e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff
763a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;}
764a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCCategoryImplDecl *D) { return true; }
7658f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian};
7668f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
767a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCImplementationDecl - Represents a class definition - this is where
7680c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// method definitions are specified. For example:
7690c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
7700c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @implementation MyClass
7710c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - (void)myMethod { /* do something */ }
7720c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @end
7730c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
7740c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Typically, instance variables are specified in the class interface,
7750c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// *not* in the implemenentation. Nevertheless (for legacy reasons), we
7760c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// allow instance variables to be specified in the implementation. When
7770c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// specified, they need to be *identical* to the interface. Now that we
7780c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// have support for non-fragile ivars in ObjC 2.0, we can consider removing
7790c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// the legacy semantics and allow developers to move private ivar declarations
7800c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// from the class interface to the class implementation (but I digress:-)
7810c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
782a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCImplementationDecl : public NamedDecl {
783f4d331dd922f92478ebf30e808c0ca97ce49418bFariborz Jahanian  /// Class interface for this category implementation
784a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *ClassInterface;
785f4d331dd922f92478ebf30e808c0ca97ce49418bFariborz Jahanian
786980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Implementation Class's super class.
787a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *SuperClass;
788980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
789980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Optional Ivars/NumIvars - This is a new[]'d array of pointers to Decls.
790a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCIvarDecl **Ivars;   // Null if not specified
791980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  int NumIvars;   // -1 if not defined.
7920416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff
793980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// implemented instance methods
794a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  llvm::SmallVector<ObjCMethodDecl*, 32> InstanceMethods;
7950416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff
796980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// implemented class methods
797a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods;
7980416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff
7990416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  SourceLocation EndLoc;
8009fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattnerpublic:
801a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCImplementationDecl(SourceLocation L, IdentifierInfo *Id,
802a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                         ObjCInterfaceDecl *classInterface,
803a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                         ObjCInterfaceDecl *superDecl)
804a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    : NamedDecl(ObjCImplementation, L, Id),
8050416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff      ClassInterface(classInterface), SuperClass(superDecl),
8060416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff      Ivars(0), NumIvars(-1) {}
807980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
808a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void ObjCAddInstanceVariablesToClassImpl(ObjCIvarDecl **ivars,
809980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff                                           unsigned numIvars);
810980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
811a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void addInstanceMethod(ObjCMethodDecl *method) {
8120416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff    InstanceMethods.push_back(method);
8130416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  }
814a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void addClassMethod(ObjCMethodDecl *method) {
8150416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff    ClassMethods.push_back(method);
8160416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  }
8170416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  // Location information, modeled after the Stmt API.
8180416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  SourceLocation getLocStart() const { return getLocation(); }
8190416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
8200416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
8210416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff
822a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
823a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
824980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
825a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setSuperClass(ObjCInterfaceDecl * superCls)
826980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff         { SuperClass = superCls; }
827980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
82849747fdd0a05dfc1f15910267d6f86dfe83e6fc8Steve Naroff  int getNumInstanceMethods() const { return InstanceMethods.size(); }
82949747fdd0a05dfc1f15910267d6f86dfe83e6fc8Steve Naroff  int getNumClassMethods() const { return ClassMethods.size(); }
830c43d868355374d48296ad3be2c9c536698a5e9a8Steve Naroff
83149747fdd0a05dfc1f15910267d6f86dfe83e6fc8Steve Naroff  int getImplDeclNumIvars() const { return NumIvars; }
8320157c5144513438bb74aebf50d18f95df4104acbChris Lattner
8330157c5144513438bb74aebf50d18f95df4104acbChris Lattner
834a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
8350157c5144513438bb74aebf50d18f95df4104acbChris Lattner       instmeth_iterator;
8360157c5144513438bb74aebf50d18f95df4104acbChris Lattner  instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
8370157c5144513438bb74aebf50d18f95df4104acbChris Lattner  instmeth_iterator instmeth_end() const { return InstanceMethods.end(); }
8380157c5144513438bb74aebf50d18f95df4104acbChris Lattner
839a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
8400157c5144513438bb74aebf50d18f95df4104acbChris Lattner    classmeth_iterator;
8410157c5144513438bb74aebf50d18f95df4104acbChris Lattner  classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); }
8420157c5144513438bb74aebf50d18f95df4104acbChris Lattner  classmeth_iterator classmeth_end() const { return ClassMethods.end(); }
8430157c5144513438bb74aebf50d18f95df4104acbChris Lattner
84494a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // Get the instance method definition for this implementation.
845a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getInstanceMethod(Selector Sel);
8460157c5144513438bb74aebf50d18f95df4104acbChris Lattner
84794a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // Get the class method definition for this implementation.
848a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl *getClassMethod(Selector Sel);
8490157c5144513438bb74aebf50d18f95df4104acbChris Lattner
850a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  typedef ObjCIvarDecl * const *ivar_iterator;
8510157c5144513438bb74aebf50d18f95df4104acbChris Lattner  ivar_iterator ivar_begin() const { return Ivars; }
85223c3bb768fd3eb24ff1a7402856405129afac0e3Chris Lattner  ivar_iterator ivar_end() const {return Ivars+(NumIvars == -1 ? 0 : NumIvars);}
8530157c5144513438bb74aebf50d18f95df4104acbChris Lattner
854980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  static bool classof(const Decl *D) {
855a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    return D->getKind() == ObjCImplementation;
856980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
857a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCImplementationDecl *D) { return true; }
858980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
859243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian
860a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
861243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian/// declared as @compatibility_alias alias class.
862a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCCompatibleAliasDecl : public ScopedDecl {
863243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  /// Class that this is an alias of.
864a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *AliasedClass;
865243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian
866243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanianpublic:
867a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCompatibleAliasDecl(SourceLocation L, IdentifierInfo *Id,
868a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                         ObjCInterfaceDecl* aliasedClass)
869243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  : ScopedDecl(CompatibleAlias, L, Id, 0),
870243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  AliasedClass(aliasedClass) {}
871243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian
872a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
873980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
874243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  static bool classof(const Decl *D) {
875243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian    return D->getKind() == CompatibleAlias;
876243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  }
877a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCCompatibleAliasDecl *D) { return true; }
878243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian
879243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian};
88082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
881a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCPropertyDecl : public Decl {
88282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanianpublic:
883564576b225386cbff375351597dd5e2a92872d38Fariborz Jahanian  enum PropertyAttributeKind { OBJC_PR_noattr = 0x0,
88482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_readonly = 0x01,
88582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_getter = 0x02,
88682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_assign = 0x04,
88782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_readwrite = 0x08,
88882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_retain = 0x10,
88982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_copy = 0x20,
89082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_nonatomic = 0x40,
89182a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_setter = 0x80 };
89282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanianprivate:
89382a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  // List of property name declarations
89482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  // FIXME: Property is not an ivar.
895a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCIvarDecl **PropertyDecls;
89682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  int NumPropertyDecls;
897ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek
898ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  // NOTE: VC++ treats enums as signed, avoid using PropertyAttributeKind enum
899ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  unsigned PropertyAttributes : 8;
90082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
90182a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  IdentifierInfo *GetterName;    // getter name of NULL if no getter
90282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  IdentifierInfo *SetterName;    // setter name of NULL if no setter
90382a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
90482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanianpublic:
905a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCPropertyDecl(SourceLocation L)
90682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  : Decl(PropertyDecl, L),
90782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  PropertyDecls(0), NumPropertyDecls(-1), PropertyAttributes(OBJC_PR_noattr),
90882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  GetterName(0), SetterName(0) {}
90982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
910a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCIvarDecl **const getPropertyDecls() const { return PropertyDecls; }
911a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setPropertyDecls(ObjCIvarDecl **property) { PropertyDecls = property; }
91282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
91382a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  const int getNumPropertyDecls() const { return NumPropertyDecls; }
91482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  void setNumPropertyDecls(int num) { NumPropertyDecls = num; }
91582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
916564576b225386cbff375351597dd5e2a92872d38Fariborz Jahanian  const PropertyAttributeKind getPropertyAttributes() const
917ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek    { return PropertyAttributeKind(PropertyAttributes); }
918564576b225386cbff375351597dd5e2a92872d38Fariborz Jahanian  void setPropertyAttributes(PropertyAttributeKind PRVal) {
91982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian    PropertyAttributes =
920564576b225386cbff375351597dd5e2a92872d38Fariborz Jahanian    (PropertyAttributeKind) (PropertyAttributes | PRVal);
92182a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  }
92282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
92382a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  const IdentifierInfo *getGetterName() const { return GetterName; }
92482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  IdentifierInfo *getGetterName() { return GetterName; }
92582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  void setGetterName(IdentifierInfo *Id) { GetterName = Id; }
92682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
92782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  const IdentifierInfo *getSetterName() const { return SetterName; }
92882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  IdentifierInfo *getSetterName() { return SetterName; }
92982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  void setSetterName(IdentifierInfo *Id) { SetterName = Id; }
93082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
93182a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  static bool classof(const Decl *D) {
93282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian    return D->getKind() == PropertyDecl;
93382a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  }
934a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCPropertyDecl *D) { return true; }
93582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian};
936980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
937980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff}  // end namespace clang
938980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff#endif
939