DeclObjC.h revision 23c3bb768fd3eb24ff1a7402856405129afac0e3
1980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff//===--- DeclObjC.h - Classes for representing declarations -----*- C++ -*-===//
2980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff//
3980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff//                     The LLVM Compiler Infrastructure
4980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff//
5980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff// This file was developed by Steve Naroff and is distributed under
6980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff// the University of Illinois Open Source 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;
25980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass ObjcIvarDecl;
26980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass ObjcMethodDecl;
27980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass ObjcProtocolDecl;
28980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass ObjcCategoryDecl;
2982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanianclass ObjcPropertyDecl;
30b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian
310c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// ObjcInterfaceDecl - Represents an ObjC class declaration. For example:
320c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
330c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   // MostPrimitive declares no super class (not particularly useful).
340c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @interface MostPrimitive
350c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     // no instance variables or methods.
360c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @end
370c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
38fd5de471478a507dd2495c4ea9bcab801ea5fa65Chris Lattner///   // NSResponder inherits from NSObject & implements NSCoding (a protocol).
390c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @interface NSResponder : NSObject <NSCoding>
400c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   { // instance variables are represented by ObjcIvarDecl.
410c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id nextResponder; // nextResponder instance variable.
420c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   }
430c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   - (NSResponder *)nextResponder; // return a pointer to NSResponder.
440c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
450c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @end                                    // to an NSEvent.
460c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
470c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   Unlike C/C++, forward class declarations are accomplished with @class.
480c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   Unlike C/C++, @class allows for a list of classes to be forward declared.
490c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
500c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   typically inherit from NSObject (an exception is NSProxy).
510c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
52980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass ObjcInterfaceDecl : public TypeDecl {
53980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
54980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Class's super class.
55980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  ObjcInterfaceDecl *SuperClass;
56980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
57980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Protocols referenced in interface header declaration
587ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  ObjcProtocolDecl **ReferencedProtocols;  // Null if none
597ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumReferencedProtocols;  // -1 if none
60980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
61980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Ivars/NumIvars - This is a new[]'d array of pointers to Decls.
62980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  ObjcIvarDecl **Ivars;   // Null if not defined.
63980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  int NumIvars;   // -1 if not defined.
64980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
65980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// instance methods
667ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  ObjcMethodDecl **InstanceMethods;  // Null if not defined
677ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumInstanceMethods;  // -1 if not defined
68980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
69980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// class methods
707ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  ObjcMethodDecl **ClassMethods;  // Null if not defined
717ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumClassMethods;  // -1 if not defined
72980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
73980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// List of categories defined for this class.
743d58138992b9bc7b34aaa680f3ddf3971292eb7dSteve Naroff  ObjcCategoryDecl *CategoryList;
7582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
7682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  /// class properties
7782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  ObjcPropertyDecl **PropertyDecl;  // Null if no property
7882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  int NumPropertyDecl;  // -1 if no property
79980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
803a3ca1b35a7121aea0bf465a192dce748465e10fFariborz Jahanian  bool ForwardDecl:1; // declared with @class.
813a3ca1b35a7121aea0bf465a192dce748465e10fFariborz Jahanian  bool InternalInterface:1; // true - no @interface for @implementation
8260fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff
83f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  SourceLocation EndLoc; // marks the '>', '}', or identifier.
84f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  SourceLocation AtEndLoc; // marks the end of the entire interface.
85980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffpublic:
8660fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff  ObjcInterfaceDecl(SourceLocation atLoc, unsigned numRefProtos,
873a3ca1b35a7121aea0bf465a192dce748465e10fFariborz Jahanian                    IdentifierInfo *Id, bool FD = false,
883a3ca1b35a7121aea0bf465a192dce748465e10fFariborz Jahanian                    bool isInternal = false)
8960fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff    : TypeDecl(ObjcInterface, atLoc, Id, 0), SuperClass(0),
907ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      ReferencedProtocols(0), NumReferencedProtocols(-1), Ivars(0),
917ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      NumIvars(-1),
927ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      InstanceMethods(0), NumInstanceMethods(-1),
937ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      ClassMethods(0), NumClassMethods(-1),
9482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian      CategoryList(0), PropertyDecl(0), NumPropertyDecl(-1),
9582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian      ForwardDecl(FD), InternalInterface(isInternal) {
96980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff        AllocIntfRefProtocols(numRefProtos);
97980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      }
98a5997c4f36e0f5aa44623a5b1e3b914760d1ec68Steve Naroff
99a5997c4f36e0f5aa44623a5b1e3b914760d1ec68Steve Naroff  // This is necessary when converting a forward declaration to a definition.
100980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void AllocIntfRefProtocols(unsigned numRefProtos) {
101980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    if (numRefProtos) {
1027ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      ReferencedProtocols = new ObjcProtocolDecl*[numRefProtos];
1037ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      memset(ReferencedProtocols, '\0',
104980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff             numRefProtos*sizeof(ObjcProtocolDecl*));
1057ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      NumReferencedProtocols = numRefProtos;
106980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    }
107980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
108980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
1097ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  ObjcProtocolDecl **getReferencedProtocols() const {
1107ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    return ReferencedProtocols;
1117ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  }
1127ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumIntfRefProtocols() const { return NumReferencedProtocols; }
113980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
1140330071714f1ba09e926becd666f4fc0ed62bc0bSteve Naroff  int getNumInstanceVariables() const { return NumIvars; }
115980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
116be6df088d69bca0e99c7845a6cd8c1ca85034f31Chris Lattner  typedef ObjcIvarDecl * const *ivar_iterator;
117be6df088d69bca0e99c7845a6cd8c1ca85034f31Chris Lattner  ivar_iterator ivar_begin() const { return Ivars; }
118be6df088d69bca0e99c7845a6cd8c1ca85034f31Chris Lattner  ivar_iterator ivar_end() const { return Ivars+(NumIvars == -1 ?0 : NumIvars);}
119be6df088d69bca0e99c7845a6cd8c1ca85034f31Chris Lattner
1207ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  ObjcMethodDecl** getInstanceMethods() const { return InstanceMethods; }
1217ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumInstanceMethods() const { return NumInstanceMethods; }
122980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
1237ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  ObjcMethodDecl** getClassMethods() const { return ClassMethods; }
1247ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumClassMethods() const { return NumClassMethods; }
125980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
1264c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  typedef ObjcMethodDecl * const * instmeth_iterator;
1274c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  instmeth_iterator instmeth_begin() const { return InstanceMethods; }
1284c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  instmeth_iterator instmeth_end() const {
12923c3bb768fd3eb24ff1a7402856405129afac0e3Chris Lattner    return InstanceMethods+(NumInstanceMethods == -1 ? 0 : NumInstanceMethods);
1304c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  }
1314c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner
1324c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  typedef ObjcMethodDecl * const * classmeth_iterator;
1334c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  classmeth_iterator classmeth_begin() const { return ClassMethods; }
1344c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  classmeth_iterator classmeth_end() const {
13523c3bb768fd3eb24ff1a7402856405129afac0e3Chris Lattner    return ClassMethods+(NumClassMethods == -1 ? 0 : NumClassMethods);
1364c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  }
1374c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner
13860fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff  void addInstanceVariablesToClass(ObjcIvarDecl **ivars, unsigned numIvars,
13960fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff                                   SourceLocation RBracLoc);
140980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
14160fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff  void addMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers,
14260fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff                  ObjcMethodDecl **clsMethods, unsigned numClsMembers,
14360fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff                  SourceLocation AtEnd);
144980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
145768f26ee5892cd63ff0335a15d71a2385ba7c5eaSteve Naroff  bool isForwardDecl() const { return ForwardDecl; }
146768f26ee5892cd63ff0335a15d71a2385ba7c5eaSteve Naroff  void setForwardDecl(bool val) { ForwardDecl = val; }
147980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
148980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void setIntfRefProtocols(int idx, ObjcProtocolDecl *OID) {
1497ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    assert((idx < NumReferencedProtocols) && "index out of range");
1507ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    ReferencedProtocols[idx] = OID;
151980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
152980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
153980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  ObjcInterfaceDecl *getSuperClass() const { return SuperClass; }
154980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void setSuperClass(ObjcInterfaceDecl * superCls) { SuperClass = superCls; }
155980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
1563d58138992b9bc7b34aaa680f3ddf3971292eb7dSteve Naroff  ObjcCategoryDecl* getCategoryList() const { return CategoryList; }
1573d58138992b9bc7b34aaa680f3ddf3971292eb7dSteve Naroff  void setCategoryList(ObjcCategoryDecl *category) {
1583d58138992b9bc7b34aaa680f3ddf3971292eb7dSteve Naroff         CategoryList = category;
159980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
1600330071714f1ba09e926becd666f4fc0ed62bc0bSteve Naroff  ObjcIvarDecl *lookupInstanceVariable(IdentifierInfo *ivarName,
1610330071714f1ba09e926becd666f4fc0ed62bc0bSteve Naroff                                       ObjcInterfaceDecl *&clsDeclared);
1626a8a9a41e9067b708498c02180159bafecfa044fSteve Naroff  ObjcMethodDecl *lookupInstanceMethod(Selector &Sel);
1636a8a9a41e9067b708498c02180159bafecfa044fSteve Naroff  ObjcMethodDecl *lookupClassMethod(Selector &Sel);
16460fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff
165f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  // Location information, modeled after the Stmt API.
16660fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff  SourceLocation getLocStart() const { return getLocation(); } // '@'interface
167f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
168f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
16960fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff
17060fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff  // We also need to record the @end location.
171f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  SourceLocation getAtEndLoc() const { return AtEndLoc; }
17282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
173ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  int getNumPropertyDecl() const { return NumPropertyDecl; }
17482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  void setNumPropertyDecl(int num) { NumPropertyDecl = num; }
17582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
17682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  ObjcPropertyDecl **const getPropertyDecl() const { return PropertyDecl; }
17782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  ObjcPropertyDecl **getPropertyDecl() { return PropertyDecl; }
17882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  void setPropertyDecls(ObjcPropertyDecl **properties) {
17982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian    PropertyDecl = properties;
18082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  }
181f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff
1824b6df3fa953267c5d755628c8afd818bb571e579Fariborz Jahanian  /// ImplicitInterfaceDecl - check that this is an implicitely declared
1834b6df3fa953267c5d755628c8afd818bb571e579Fariborz Jahanian  /// ObjcInterfaceDecl node. This is for legacy objective-c @implementation
1844b6df3fa953267c5d755628c8afd818bb571e579Fariborz Jahanian  /// declaration without an @interface declaration.
1853a3ca1b35a7121aea0bf465a192dce748465e10fFariborz Jahanian  bool ImplicitInterfaceDecl() const { return InternalInterface; }
1864b6df3fa953267c5d755628c8afd818bb571e579Fariborz Jahanian
187aa9fc46c6a797c86ae004092ab4f2b1bed6c4616Chris Lattner  static bool classof(const Decl *D) { return D->getKind() == ObjcInterface; }
188980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  static bool classof(const ObjcInterfaceDecl *D) { return true; }
189980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
190980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
1910c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// ObjcIvarDecl - Represents an ObjC instance variable. In general, ObjC
1920c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// instance variables are identical to C. The only exception is Objective-C
1930c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// supports C++ style access control. For example:
1940c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
1950c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @interface IvarExample : NSObject
1960c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   {
1970c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id defaultToPrivate; // same as C++.
1980c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @public:
1990c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id canBePublic; // same as C++.
2000c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @protected:
2010c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id canBeProtected; // same as C++.
2020c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @package:
2030c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id canBePackage; // framework visibility (not available in C++).
2040c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   }
2050c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
206980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass ObjcIvarDecl : public FieldDecl {
207980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffpublic:
208980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  ObjcIvarDecl(SourceLocation L, IdentifierInfo *Id, QualType T)
209980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    : FieldDecl(ObjcIvar, L, Id, T) {}
210980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
211980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  enum AccessControl {
212980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    None, Private, Protected, Public, Package
213980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  };
214980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void setAccessControl(AccessControl ac) { DeclAccess = ac; }
215980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  AccessControl getAccessControl() const { return DeclAccess; }
216980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
217980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  // Implement isa/cast/dyncast/etc.
218980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  static bool classof(const Decl *D) { return D->getKind() == ObjcIvar; }
219980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  static bool classof(const ObjcIvarDecl *D) { return true; }
220980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffprivate:
221980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  AccessControl DeclAccess : 3;
222980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
223980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
224980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
2250c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// ObjcProtocolDecl - Represents a protocol declaration. ObjC protocols
2260c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// declare a pure abstract type (i.e no instance variables are permitted).
2270c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Protocols orginally drew inspiration from C++ pure virtual functions (a C++
2280c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// feature with nice semantics and lousy syntax:-). Here is an example:
2290c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
2300c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @protocol NSDraggingInfo
2310c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - (NSWindow *)draggingDestinationWindow;
2320c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - (NSImage *)draggedImage;
2330c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @end
2340c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
2350c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @interface ImplementsNSDraggingInfo : NSObject <NSDraggingInfo>
2360c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @end
2370c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
2380c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Objc protocols inspired Java interfaces. Unlike Java, ObjC classes and
2390c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// protocols are in distinct namespaces. For example, Cocoa defines both
2400c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// an NSObject protocol and class (which isn't allowed in Java). As a result,
2410c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// protocols are referenced using angle brackets as follows:
2420c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
2430c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// id <NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
2440c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
24505672a0ce85f6a203a960a856d30c4606ab136a7Fariborz Jahanianclass ObjcProtocolDecl : public NamedDecl {
246980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// referenced protocols
247980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  ObjcProtocolDecl **ReferencedProtocols;  // Null if none
248980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  int NumReferencedProtocols;  // -1 if none
249980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
250980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// protocol instance methods
2517ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  ObjcMethodDecl **InstanceMethods;  // Null if not defined
2527ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumInstanceMethods;  // -1 if not defined
253980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
254980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// protocol class methods
2557ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  ObjcMethodDecl **ClassMethods;  // Null if not defined
2567ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumClassMethods;  // -1 if not defined
257980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
258980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  bool isForwardProtoDecl; // declared with @protocol.
259423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff
260423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation EndLoc; // marks the '>' or identifier.
261423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation AtEndLoc; // marks the end of the entire interface.
262980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffpublic:
263980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  ObjcProtocolDecl(SourceLocation L, unsigned numRefProtos,
264980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff                   IdentifierInfo *Id, bool FD = false)
26505672a0ce85f6a203a960a856d30c4606ab136a7Fariborz Jahanian    : NamedDecl(ObjcProtocol, L, Id),
266980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      ReferencedProtocols(0), NumReferencedProtocols(-1),
2677ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      InstanceMethods(0), NumInstanceMethods(-1),
2687ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      ClassMethods(0), NumClassMethods(-1),
269980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      isForwardProtoDecl(FD) {
270980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff        AllocReferencedProtocols(numRefProtos);
271980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      }
272980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void AllocReferencedProtocols(unsigned numRefProtos) {
273980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    if (numRefProtos) {
274980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      ReferencedProtocols = new ObjcProtocolDecl*[numRefProtos];
275980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      memset(ReferencedProtocols, '\0',
276980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff             numRefProtos*sizeof(ObjcProtocolDecl*));
277980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      NumReferencedProtocols = numRefProtos;
278980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    }
279980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
28060fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff  void addMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers,
28160fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff                  ObjcMethodDecl **clsMethods, unsigned numClsMembers,
28260fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff                  SourceLocation AtEndLoc);
283980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
284980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void setReferencedProtocols(int idx, ObjcProtocolDecl *OID) {
285980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    assert((idx < NumReferencedProtocols) && "index out of range");
286980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    ReferencedProtocols[idx] = OID;
287980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
288980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
289980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  ObjcProtocolDecl** getReferencedProtocols() const {
290980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    return ReferencedProtocols;
291980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
292980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  int getNumReferencedProtocols() const { return NumReferencedProtocols; }
293980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
2947ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  ObjcMethodDecl** getInstanceMethods() const { return InstanceMethods; }
2957ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumInstanceMethods() const { return NumInstanceMethods; }
296980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
2977ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  ObjcMethodDecl** getClassMethods() const { return ClassMethods; }
2987ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumClassMethods() const { return NumClassMethods; }
299980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
3007dd82836dca87cf828ce994f161b53a34f6cdb7eFariborz Jahanian  ObjcMethodDecl *lookupInstanceMethod(Selector &Sel);
3017dd82836dca87cf828ce994f161b53a34f6cdb7eFariborz Jahanian  ObjcMethodDecl *lookupClassMethod(Selector &Sel);
3027dd82836dca87cf828ce994f161b53a34f6cdb7eFariborz Jahanian
303768f26ee5892cd63ff0335a15d71a2385ba7c5eaSteve Naroff  bool isForwardDecl() const { return isForwardProtoDecl; }
304768f26ee5892cd63ff0335a15d71a2385ba7c5eaSteve Naroff  void setForwardDecl(bool val) { isForwardProtoDecl = val; }
305980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
306423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  // Location information, modeled after the Stmt API.
307423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getLocStart() const { return getLocation(); } // '@'protocol
308423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
309423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
310423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff
311423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  // We also need to record the @end location.
312423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getAtEndLoc() const { return AtEndLoc; }
313423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff
314aa9fc46c6a797c86ae004092ab4f2b1bed6c4616Chris Lattner  static bool classof(const Decl *D) { return D->getKind() == ObjcProtocol; }
315980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  static bool classof(const ObjcProtocolDecl *D) { return true; }
316980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
317980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
31806ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff/// ObjcClassDecl - Specifies a list of forward class declarations. For example:
31906ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff///
32006ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff/// @class NSCursor, NSImage, NSPasteboard, NSWindow;
3210c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
322ab0aeb0bf3eb289013e9f37e75c3dfc4c618f53cFariborz Jahanianclass ObjcClassDecl : public Decl {
3237e620729fcb5a0042107f999dcf524f7357ce819Chris Lattner  ObjcInterfaceDecl **ForwardDecls;
3247e620729fcb5a0042107f999dcf524f7357ce819Chris Lattner  unsigned NumForwardDecls;
32506ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroffpublic:
3267e620729fcb5a0042107f999dcf524f7357ce819Chris Lattner  ObjcClassDecl(SourceLocation L, ObjcInterfaceDecl **Elts, unsigned nElts)
327ab0aeb0bf3eb289013e9f37e75c3dfc4c618f53cFariborz Jahanian    : Decl(ObjcClass, L) {
32806ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff    if (nElts) {
32906ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff      ForwardDecls = new ObjcInterfaceDecl*[nElts];
3307e620729fcb5a0042107f999dcf524f7357ce819Chris Lattner      memcpy(ForwardDecls, Elts, nElts*sizeof(ObjcInterfaceDecl*));
3317e620729fcb5a0042107f999dcf524f7357ce819Chris Lattner    } else {
3327e620729fcb5a0042107f999dcf524f7357ce819Chris Lattner      ForwardDecls = 0;
33306ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff    }
33406ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff    NumForwardDecls = nElts;
33506ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  }
3367e620729fcb5a0042107f999dcf524f7357ce819Chris Lattner  void setInterfaceDecl(unsigned idx, ObjcInterfaceDecl *OID) {
3377e620729fcb5a0042107f999dcf524f7357ce819Chris Lattner    assert(idx < NumForwardDecls && "index out of range");
33806ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff    ForwardDecls[idx] = OID;
33906ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  }
3407e15891fc89256fc013bd1003676ad3197b85c25Steve Naroff  ObjcInterfaceDecl** getForwardDecls() const { return ForwardDecls; }
3417e15891fc89256fc013bd1003676ad3197b85c25Steve Naroff  int getNumForwardDecls() const { return NumForwardDecls; }
3427e15891fc89256fc013bd1003676ad3197b85c25Steve Naroff
343aa9fc46c6a797c86ae004092ab4f2b1bed6c4616Chris Lattner  static bool classof(const Decl *D) { return D->getKind() == ObjcClass; }
34406ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  static bool classof(const ObjcClassDecl *D) { return true; }
34506ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff};
34606ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff
34706ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff/// ObjcForwardProtocolDecl - Specifies a list of forward protocol declarations.
34806ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff/// For example:
34906ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff///
3500c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo;
3510c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
3526d4caf26945095cc21dd7c79d2442668ed3a61b6Fariborz Jahanianclass ObjcForwardProtocolDecl : public Decl {
3539fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner  ObjcProtocolDecl **ReferencedProtocols;
3549fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner  unsigned NumReferencedProtocols;
35506ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroffpublic:
356b97de3eddf0a0f7ff97204e7def6b7e0aa8953f2Chris Lattner  ObjcForwardProtocolDecl(SourceLocation L,
357b97de3eddf0a0f7ff97204e7def6b7e0aa8953f2Chris Lattner                          ObjcProtocolDecl **Elts, unsigned nElts)
3586d4caf26945095cc21dd7c79d2442668ed3a61b6Fariborz Jahanian  : Decl(ObjcForwardProtocol, L) {
359b97de3eddf0a0f7ff97204e7def6b7e0aa8953f2Chris Lattner    NumReferencedProtocols = nElts;
36006ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff    if (nElts) {
3617ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      ReferencedProtocols = new ObjcProtocolDecl*[nElts];
362b97de3eddf0a0f7ff97204e7def6b7e0aa8953f2Chris Lattner      memcpy(ReferencedProtocols, Elts, nElts*sizeof(ObjcProtocolDecl*));
3639fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    } else {
3649fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner      ReferencedProtocols = 0;
365980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    }
36606ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  }
3679fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner  void setForwardProtocolDecl(unsigned idx, ObjcProtocolDecl *OID) {
3689fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    assert(idx < NumReferencedProtocols && "index out of range");
3697ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    ReferencedProtocols[idx] = OID;
37006ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  }
3719fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner
3729fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner  unsigned getNumForwardDecls() const { return NumReferencedProtocols; }
3739fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner
3749fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner  ObjcProtocolDecl *getForwardProtocolDecl(unsigned idx) {
3759fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    assert(idx < NumReferencedProtocols && "index out of range");
3769fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    return ReferencedProtocols[idx];
3779fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner  }
3789fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner  const ObjcProtocolDecl *getForwardProtocolDecl(unsigned idx) const {
3799fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    assert(idx < NumReferencedProtocols && "index out of range");
3809fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner    return ReferencedProtocols[idx];
3819fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner  }
3829fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattner
38306ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  static bool classof(const Decl *D) {
38406ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff    return D->getKind() == ObjcForwardProtocol;
38506ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  }
38606ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  static bool classof(const ObjcForwardProtocolDecl *D) { return true; }
387980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
388980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
3890c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// ObjcCategoryDecl - Represents a category declaration. A category allows
3900c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// you to add methods to an existing class (without subclassing or modifying
3910c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// the original class interface or implementation:-). Categories don't allow
3920c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// you to add instance data. The following example adds "myMethod" to all
3930c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// NSView's within a process:
3940c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
3950c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @interface NSView (MyViewMethods)
3960c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - myMethod;
3970c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @end
3980c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
3990c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Cateogries also allow you to split the implementation of a class across
4000c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// several files (a feature more naturally supported in C++).
4010c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
4020c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Categories were originally inspired by dynamic languages such as Common
4030c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Lisp and Smalltalk. More traditional class-based languages (C++, Java)
4040c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// don't support this level of dynamism, which is both powerful and dangerous.
4050c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
406fd5de471478a507dd2495c4ea9bcab801ea5fa65Chris Lattnerclass ObjcCategoryDecl : public NamedDecl {
407980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Interface belonging to this category
408980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  ObjcInterfaceDecl *ClassInterface;
409980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
410980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// referenced protocols in this category
4117ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  ObjcProtocolDecl **ReferencedProtocols;  // Null if none
4127ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumReferencedProtocols;  // -1 if none
413980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
414980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// category instance methods
4157ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  ObjcMethodDecl **InstanceMethods;  // Null if not defined
4167ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumInstanceMethods;  // -1 if not defined
417980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
418980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// category class methods
4197ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  ObjcMethodDecl **ClassMethods;  // Null if not defined
4207ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int NumClassMethods;  // -1 if not defined
421980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
422980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Next category belonging to this class
423980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  ObjcCategoryDecl *NextClassCategory;
424ca3adf7e8cac8c9fbaf592b1e5c2be6f082de7baFariborz Jahanian
425423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation EndLoc; // marks the '>' or identifier.
426423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation AtEndLoc; // marks the end of the entire interface.
427980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffpublic:
428fd5de471478a507dd2495c4ea9bcab801ea5fa65Chris Lattner  ObjcCategoryDecl(SourceLocation L, unsigned numRefProtocol,IdentifierInfo *Id)
429fd5de471478a507dd2495c4ea9bcab801ea5fa65Chris Lattner    : NamedDecl(ObjcCategory, L, Id),
430fd5de471478a507dd2495c4ea9bcab801ea5fa65Chris Lattner      ClassInterface(0), ReferencedProtocols(0), NumReferencedProtocols(-1),
4317ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      InstanceMethods(0), NumInstanceMethods(-1),
4327ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian      ClassMethods(0), NumClassMethods(-1),
433e5ab7f31054e87ee812830480a828a762cd9eb73Chris Lattner      NextClassCategory(0) {
434980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff        if (numRefProtocol) {
4357ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian          ReferencedProtocols = new ObjcProtocolDecl*[numRefProtocol];
4367ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian          memset(ReferencedProtocols, '\0',
437980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff                 numRefProtocol*sizeof(ObjcProtocolDecl*));
4387ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian          NumReferencedProtocols = numRefProtocol;
439980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff        }
440980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff      }
441980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
442980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  ObjcInterfaceDecl *getClassInterface() const { return ClassInterface; }
443980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void setClassInterface(ObjcInterfaceDecl *IDecl) { ClassInterface = IDecl; }
444980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
445980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void setCatReferencedProtocols(int idx, ObjcProtocolDecl *OID) {
4467ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    assert((idx < NumReferencedProtocols) && "index out of range");
4477ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    ReferencedProtocols[idx] = OID;
448980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
449980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
4507ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  ObjcProtocolDecl **getReferencedProtocols() const {
4517ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian    return ReferencedProtocols;
4528f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian  }
4537ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumReferencedProtocols() const { return NumReferencedProtocols; }
4548f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
4557ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  ObjcMethodDecl **getInstanceMethods() const { return InstanceMethods; }
4567ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumInstanceMethods() const { return NumInstanceMethods; }
4578f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
4587ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  ObjcMethodDecl **getClassMethods() const { return ClassMethods; }
4597ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  int getNumClassMethods() const { return NumClassMethods; }
4608f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
46160fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff  void addMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers,
46260fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff                  ObjcMethodDecl **clsMethods, unsigned numClsMembers,
46360fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff                  SourceLocation AtEndLoc);
464980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
465980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  ObjcCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
466980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void insertNextClassCategory() {
4673d58138992b9bc7b34aaa680f3ddf3971292eb7dSteve Naroff    NextClassCategory = ClassInterface->getCategoryList();
4683d58138992b9bc7b34aaa680f3ddf3971292eb7dSteve Naroff    ClassInterface->setCategoryList(this);
469980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
470423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  // Location information, modeled after the Stmt API.
471423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getLocStart() const { return getLocation(); } // '@'interface
472423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
473423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
474423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff
475423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  // We also need to record the @end location.
476423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getAtEndLoc() const { return AtEndLoc; }
477ca3adf7e8cac8c9fbaf592b1e5c2be6f082de7baFariborz Jahanian
478aa9fc46c6a797c86ae004092ab4f2b1bed6c4616Chris Lattner  static bool classof(const Decl *D) { return D->getKind() == ObjcCategory; }
479980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  static bool classof(const ObjcCategoryDecl *D) { return true; }
480980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
4810c6b6243d3efd958c17943130e2a773653511edcSteve Naroff
4828f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian/// ObjcCategoryImplDecl - An object of this class encapsulates a category
4838f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian/// @implementation declaration.
4846a0e89eece63e238ce873810f6f9bb50822e0296Chris Lattnerclass ObjcCategoryImplDecl : public NamedDecl {
4858f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian  /// Class interface for this category implementation
4868f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian  ObjcInterfaceDecl *ClassInterface;
4878f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
488e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  /// implemented instance methods
489e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  llvm::SmallVector<ObjcMethodDecl*, 32> InstanceMethods;
4908f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
491e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  /// implemented class methods
492e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  llvm::SmallVector<ObjcMethodDecl*, 32> ClassMethods;
493e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff
494e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  SourceLocation EndLoc;
495e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroffpublic:
496ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  ObjcCategoryImplDecl(SourceLocation L, IdentifierInfo *Id,
497ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner                       ObjcInterfaceDecl *classInterface)
498ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner    : NamedDecl(ObjcCategoryImpl, L, Id), ClassInterface(classInterface) {}
4998f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
500e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  ObjcInterfaceDecl *getClassInterface() const { return ClassInterface; }
5018f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
502ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  unsigned getNumInstanceMethods() const { return InstanceMethods.size(); }
503ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  unsigned getNumClassMethods() const { return ClassMethods.size(); }
504e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff
505e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  void addInstanceMethod(ObjcMethodDecl *method) {
506e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff    InstanceMethods.push_back(method);
507e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  }
508e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  void addClassMethod(ObjcMethodDecl *method) {
509e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff    ClassMethods.push_back(method);
510e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  }
511e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  ObjcMethodDecl *lookupInstanceMethod(Selector &Sel);
512e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  ObjcMethodDecl *lookupClassMethod(Selector &Sel);
513e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff
514ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  typedef llvm::SmallVector<ObjcMethodDecl*, 32>::const_iterator
515ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner    instmeth_iterator;
516ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
517ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  instmeth_iterator instmeth_end() const { return InstanceMethods.end(); }
518ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner
519ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  typedef llvm::SmallVector<ObjcMethodDecl*, 32>::const_iterator
520ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner    classmeth_iterator;
521ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); }
522ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  classmeth_iterator classmeth_end() const { return ClassMethods.end(); }
523ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner
524ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner
525e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  // Location information, modeled after the Stmt API.
526e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  SourceLocation getLocStart() const { return getLocation(); }
527e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
528e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
529e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff
530aa9fc46c6a797c86ae004092ab4f2b1bed6c4616Chris Lattner  static bool classof(const Decl *D) { return D->getKind() == ObjcCategoryImpl;}
5318f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian  static bool classof(const ObjcCategoryImplDecl *D) { return true; }
5328f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian};
5338f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
5340c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// ObjcImplementationDecl - Represents a class definition - this is where
5350c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// method definitions are specified. For example:
5360c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
5370c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @implementation MyClass
5380c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - (void)myMethod { /* do something */ }
5390c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @end
5400c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
5410c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Typically, instance variables are specified in the class interface,
5420c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// *not* in the implemenentation. Nevertheless (for legacy reasons), we
5430c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// allow instance variables to be specified in the implementation. When
5440c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// specified, they need to be *identical* to the interface. Now that we
5450c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// have support for non-fragile ivars in ObjC 2.0, we can consider removing
5460c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// the legacy semantics and allow developers to move private ivar declarations
5470c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// from the class interface to the class implementation (but I digress:-)
5480c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
5496d4caf26945095cc21dd7c79d2442668ed3a61b6Fariborz Jahanianclass ObjcImplementationDecl : public NamedDecl {
550f4d331dd922f92478ebf30e808c0ca97ce49418bFariborz Jahanian  /// Class interface for this category implementation
551f4d331dd922f92478ebf30e808c0ca97ce49418bFariborz Jahanian  ObjcInterfaceDecl *ClassInterface;
552f4d331dd922f92478ebf30e808c0ca97ce49418bFariborz Jahanian
553980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Implementation Class's super class.
554980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  ObjcInterfaceDecl *SuperClass;
555980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
556980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Optional Ivars/NumIvars - This is a new[]'d array of pointers to Decls.
557980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  ObjcIvarDecl **Ivars;   // Null if not specified
558980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  int NumIvars;   // -1 if not defined.
5590416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff
560980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// implemented instance methods
5610416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  llvm::SmallVector<ObjcMethodDecl*, 32> InstanceMethods;
5620416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff
563980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// implemented class methods
5640416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  llvm::SmallVector<ObjcMethodDecl*, 32> ClassMethods;
5650416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff
5660416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  SourceLocation EndLoc;
5679fa5e65d08aee1875c5f2a841c8b0b4069bd00e5Chris Lattnerpublic:
568980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  ObjcImplementationDecl(SourceLocation L, IdentifierInfo *Id,
569f4d331dd922f92478ebf30e808c0ca97ce49418bFariborz Jahanian                         ObjcInterfaceDecl *classInterface,
570f4d331dd922f92478ebf30e808c0ca97ce49418bFariborz Jahanian                         ObjcInterfaceDecl *superDecl)
5716d4caf26945095cc21dd7c79d2442668ed3a61b6Fariborz Jahanian    : NamedDecl(ObjcImplementation, L, Id),
5720416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff      ClassInterface(classInterface), SuperClass(superDecl),
5730416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff      Ivars(0), NumIvars(-1) {}
574980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
575980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void ObjcAddInstanceVariablesToClassImpl(ObjcIvarDecl **ivars,
576980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff                                           unsigned numIvars);
577980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
5780416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  void addInstanceMethod(ObjcMethodDecl *method) {
5790416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff    InstanceMethods.push_back(method);
5800416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  }
5810416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  void addClassMethod(ObjcMethodDecl *method) {
5820416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff    ClassMethods.push_back(method);
5830416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  }
5840416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  // Location information, modeled after the Stmt API.
5850416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  SourceLocation getLocStart() const { return getLocation(); }
5860416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
5870416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
5880416fb9f379b49abb3eb0c1cb2ca75107e5a71d1Steve Naroff
589f4d331dd922f92478ebf30e808c0ca97ce49418bFariborz Jahanian  ObjcInterfaceDecl *getClassInterface() const { return ClassInterface; }
59093efc029bf485de724fd783ad14b58aaec9c919bFariborz Jahanian  ObjcInterfaceDecl *getSuperClass() const { return SuperClass; }
591980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
59293efc029bf485de724fd783ad14b58aaec9c919bFariborz Jahanian  void setSuperClass(ObjcInterfaceDecl * superCls)
593980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff         { SuperClass = superCls; }
594980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
595ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  unsigned getNumInstanceMethods() const { return InstanceMethods.size(); }
596ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  unsigned getNumClassMethods() const { return ClassMethods.size(); }
597c43d868355374d48296ad3be2c9c536698a5e9a8Steve Naroff
598ab4c4d5e5ececa77aae7e291fafcba3049319cdcChris Lattner  unsigned getImplDeclNumIvars() const { return NumIvars; }
5990157c5144513438bb74aebf50d18f95df4104acbChris Lattner
6000157c5144513438bb74aebf50d18f95df4104acbChris Lattner
6010157c5144513438bb74aebf50d18f95df4104acbChris Lattner  typedef llvm::SmallVector<ObjcMethodDecl*, 32>::const_iterator
6020157c5144513438bb74aebf50d18f95df4104acbChris Lattner       instmeth_iterator;
6030157c5144513438bb74aebf50d18f95df4104acbChris Lattner  instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
6040157c5144513438bb74aebf50d18f95df4104acbChris Lattner  instmeth_iterator instmeth_end() const { return InstanceMethods.end(); }
6050157c5144513438bb74aebf50d18f95df4104acbChris Lattner
6060157c5144513438bb74aebf50d18f95df4104acbChris Lattner  typedef llvm::SmallVector<ObjcMethodDecl*, 32>::const_iterator
6070157c5144513438bb74aebf50d18f95df4104acbChris Lattner    classmeth_iterator;
6080157c5144513438bb74aebf50d18f95df4104acbChris Lattner  classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); }
6090157c5144513438bb74aebf50d18f95df4104acbChris Lattner  classmeth_iterator classmeth_end() const { return ClassMethods.end(); }
6100157c5144513438bb74aebf50d18f95df4104acbChris Lattner
6110157c5144513438bb74aebf50d18f95df4104acbChris Lattner  /// lookupInstanceMethod - This method returns an instance method by looking
6120157c5144513438bb74aebf50d18f95df4104acbChris Lattner  /// in the class implementation. Unlike interfaces, we don't look outside the
6130157c5144513438bb74aebf50d18f95df4104acbChris Lattner  /// implementation.
6140157c5144513438bb74aebf50d18f95df4104acbChris Lattner  ObjcMethodDecl *lookupInstanceMethod(Selector Sel);
6150157c5144513438bb74aebf50d18f95df4104acbChris Lattner
6160157c5144513438bb74aebf50d18f95df4104acbChris Lattner  /// lookupClassMethod - This method returns a class method by looking in
6170157c5144513438bb74aebf50d18f95df4104acbChris Lattner  /// the class implementation. Unlike interfaces, we don't look outside the
6180157c5144513438bb74aebf50d18f95df4104acbChris Lattner  /// implementation.
6190157c5144513438bb74aebf50d18f95df4104acbChris Lattner  ObjcMethodDecl *lookupClassMethod(Selector Sel);
6200157c5144513438bb74aebf50d18f95df4104acbChris Lattner
6210157c5144513438bb74aebf50d18f95df4104acbChris Lattner  typedef ObjcIvarDecl * const *ivar_iterator;
6220157c5144513438bb74aebf50d18f95df4104acbChris Lattner  ivar_iterator ivar_begin() const { return Ivars; }
62323c3bb768fd3eb24ff1a7402856405129afac0e3Chris Lattner  ivar_iterator ivar_end() const {return Ivars+(NumIvars == -1 ? 0 : NumIvars);}
6240157c5144513438bb74aebf50d18f95df4104acbChris Lattner
625980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  static bool classof(const Decl *D) {
626980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    return D->getKind() == ObjcImplementation;
627980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
628980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  static bool classof(const ObjcImplementationDecl *D) { return true; }
629980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
630243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian
631b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian/// ObjcMethodDecl - Represents an instance or class method declaration.
632b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian/// ObjC methods can be declared within 4 contexts: class interfaces,
633b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian/// categories, protocols, and class implementations. While C++ member
634b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian/// functions leverage C syntax, Objective-C method syntax is modeled after
635b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian/// Smalltalk (using colons to specify argument types/expressions).
636b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian/// Here are some brief examples:
637b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian///
638b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian/// Setter/getter instance methods:
639b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian/// - (void)setMenu:(NSMenu *)menu;
640b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian/// - (NSMenu *)menu;
641b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian///
642b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian/// Instance method that takes 2 NSView arguments:
643b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
644b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian///
645b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian/// Getter class method:
646b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian/// + (NSMenu *)defaultMenu;
647b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian///
648b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian/// A selector represents a unique name for a method. The selector names for
649b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
650b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian///
651b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanianclass ObjcMethodDecl : public Decl {
6520b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroffpublic:
6530b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  enum ImplementationControl { None, Required, Optional };
6540b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroffprivate:
6550b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  /// Bitfields must be first fields in this class so they pack with those
6560b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  /// declared in class Decl.
6570b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  /// instance (true) or class (false) method.
6580b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  bool IsInstance : 1;
659335eafa5be51f6440672a74c73d588af72e96732Steve Naroff  bool IsVariadic : 1;
660335eafa5be51f6440672a74c73d588af72e96732Steve Naroff
6610b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  /// @required/@optional
6620b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  ImplementationControl DeclImplementation : 2;
6630b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff
6640b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  /// in, inout, etc.
6650b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  ObjcDeclQualifier objcDeclQualifier : 6;
6660b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff
6670b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  // Context this method is declared in.
6680b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  NamedDecl *MethodContext;
6690b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff
6700b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  // A unigue name for this method.
6710b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  Selector SelName;
6720b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff
6730b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  // Type of this method.
6740b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  QualType MethodDeclType;
6750b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
6760b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  /// parameters of this Method.  This is null if there are no formals.
6770b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  ParmVarDecl **ParamInfo;
6780b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  int NumMethodParams;  // -1 if no parameters
6790b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff
6800b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  /// List of attributes for this method declaration.
6810b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  AttributeList *MethodAttrs;
6820b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff
6830b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  SourceLocation EndLoc; // the location of the ';' or '{'.
6849bcb5fc1fd48c1f40c6a3b5a59130ebc313b4957Steve Naroff
6859bcb5fc1fd48c1f40c6a3b5a59130ebc313b4957Steve Naroff  // The following are only used for method definitions, null otherwise.
6869bcb5fc1fd48c1f40c6a3b5a59130ebc313b4957Steve Naroff  // FIXME: space savings opportunity, consider a sub-class.
6879bcb5fc1fd48c1f40c6a3b5a59130ebc313b4957Steve Naroff  Stmt *Body;
6889bcb5fc1fd48c1f40c6a3b5a59130ebc313b4957Steve Naroff  ParmVarDecl *SelfDecl;
6890b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroffpublic:
6900b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  ObjcMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
6910b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff                 Selector SelInfo, QualType T,
6920b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff                 Decl *contextDecl,
6930b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff                 ParmVarDecl **paramInfo = 0, int numParams=-1,
6940b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff                 AttributeList *M = 0, bool isInstance = true,
695335eafa5be51f6440672a74c73d588af72e96732Steve Naroff                 bool isVariadic = false,
6960b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff                 ImplementationControl impControl = None,
6970b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff                 Decl *PrevDecl = 0)
6980b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  : Decl(ObjcMethod, beginLoc),
699335eafa5be51f6440672a74c73d588af72e96732Steve Naroff    IsInstance(isInstance), IsVariadic(isVariadic),
700335eafa5be51f6440672a74c73d588af72e96732Steve Naroff    DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
701b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian    MethodContext(static_cast<NamedDecl*>(contextDecl)),
702b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian    SelName(SelInfo), MethodDeclType(T),
703b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian    ParamInfo(paramInfo), NumMethodParams(numParams),
7049bcb5fc1fd48c1f40c6a3b5a59130ebc313b4957Steve Naroff    MethodAttrs(M), EndLoc(endLoc), Body(0), SelfDecl(0) {}
7050b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  virtual ~ObjcMethodDecl();
7060b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff
7070b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  ObjcDeclQualifier getObjcDeclQualifier() const { return objcDeclQualifier; }
7080b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  void setObjcDeclQualifier(ObjcDeclQualifier QV) { objcDeclQualifier = QV; }
7090b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff
7100b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  // Location information, modeled after the Stmt API.
7110b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  SourceLocation getLocStart() const { return getLocation(); }
7120b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
7130b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff
7140b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  NamedDecl *getMethodContext() const { return MethodContext; }
7150b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff
7160b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  ObjcInterfaceDecl *const getClassInterface() const {
7170b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff    if (ObjcInterfaceDecl *ID = dyn_cast<ObjcInterfaceDecl>(MethodContext))
7180b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff      return ID;
7190b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff    if (ObjcCategoryDecl *CD = dyn_cast<ObjcCategoryDecl>(MethodContext))
7200b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff      return CD->getClassInterface();
7210b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff    if (ObjcImplementationDecl *IMD =
7220b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff        dyn_cast<ObjcImplementationDecl>(MethodContext))
7230b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff      return IMD->getClassInterface();
7240b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff    if (ObjcCategoryImplDecl *CID =
7250b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff        dyn_cast<ObjcCategoryImplDecl>(MethodContext))
7260b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff      return CID->getClassInterface();
7270b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff    assert(false && "unknown method context");
7280b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff    return 0;
7290b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  }
7300b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff
7310b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  Selector getSelector() const { return SelName; }
7320b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  QualType getResultType() const { return MethodDeclType; }
7330b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff
7340b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  int getNumParams() const { return NumMethodParams; }
7350b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  ParmVarDecl *getParamDecl(int i) const {
7360b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff    assert(i < getNumParams() && "Illegal param #");
7370b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff    return ParamInfo[i];
7380b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  }
7390b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  void setMethodParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
7400b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff
7410b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  AttributeList *getMethodAttrs() const {return MethodAttrs;}
7420b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  bool isInstance() const { return IsInstance; }
743335eafa5be51f6440672a74c73d588af72e96732Steve Naroff  bool isVariadic() const { return IsVariadic; }
744335eafa5be51f6440672a74c73d588af72e96732Steve Naroff
7450b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  // Related to protocols declared in  @protocol
7460b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  void setDeclImplementation(ImplementationControl ic) {
7470b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff    DeclImplementation = ic;
7480b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  }
7490b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  ImplementationControl getImplementationControl() const {
7500b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff    return DeclImplementation;
7510b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  }
7520b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  Stmt *const getBody() const { return Body; }
7530b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  void setBody(Stmt *B) { Body = B; }
7549bcb5fc1fd48c1f40c6a3b5a59130ebc313b4957Steve Naroff
7559bcb5fc1fd48c1f40c6a3b5a59130ebc313b4957Steve Naroff  ParmVarDecl *const getSelfDecl() const { return SelfDecl; }
7569bcb5fc1fd48c1f40c6a3b5a59130ebc313b4957Steve Naroff  void setSelfDecl(ParmVarDecl *PVD) { SelfDecl = PVD; }
7570b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff
7580b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  // Implement isa/cast/dyncast/etc.
7590b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  static bool classof(const Decl *D) { return D->getKind() == ObjcMethod; }
7600b9cc05556c47b8aa02aea57c7679ff68f196051Steve Naroff  static bool classof(const ObjcMethodDecl *D) { return true; }
761b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian};
762b245a33e6f562377946dc9cb5694a2d3cb8a98a3Fariborz Jahanian
763243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian/// ObjcCompatibleAliasDecl - Represents alias of a class. This alias is
764243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian/// declared as @compatibility_alias alias class.
765243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanianclass ObjcCompatibleAliasDecl : public ScopedDecl {
766243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  /// Class that this is an alias of.
767243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  ObjcInterfaceDecl *AliasedClass;
768243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian
769243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanianpublic:
770243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  ObjcCompatibleAliasDecl(SourceLocation L, IdentifierInfo *Id,
771243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian                         ObjcInterfaceDecl* aliasedClass)
772243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  : ScopedDecl(CompatibleAlias, L, Id, 0),
773243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  AliasedClass(aliasedClass) {}
774243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian
775243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  ObjcInterfaceDecl *getClassInterface() const { return AliasedClass; }
776980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
777243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  static bool classof(const Decl *D) {
778243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian    return D->getKind() == CompatibleAlias;
779243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  }
780243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  static bool classof(const ObjcCompatibleAliasDecl *D) { return true; }
781243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian
782243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian};
78382a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
78482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanianclass ObjcPropertyDecl : public Decl {
78582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanianpublic:
786564576b225386cbff375351597dd5e2a92872d38Fariborz Jahanian  enum PropertyAttributeKind { OBJC_PR_noattr = 0x0,
78782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_readonly = 0x01,
78882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_getter = 0x02,
78982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_assign = 0x04,
79082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_readwrite = 0x08,
79182a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_retain = 0x10,
79282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_copy = 0x20,
79382a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_nonatomic = 0x40,
79482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian                       OBJC_PR_setter = 0x80 };
79582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanianprivate:
79682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  // List of property name declarations
79782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  // FIXME: Property is not an ivar.
79882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  ObjcIvarDecl **PropertyDecls;
79982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  int NumPropertyDecls;
80082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
801564576b225386cbff375351597dd5e2a92872d38Fariborz Jahanian  PropertyAttributeKind PropertyAttributes : 8;
80282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
80382a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  IdentifierInfo *GetterName;    // getter name of NULL if no getter
80482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  IdentifierInfo *SetterName;    // setter name of NULL if no setter
80582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
80682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanianpublic:
80782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  ObjcPropertyDecl(SourceLocation L)
80882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  : Decl(PropertyDecl, L),
80982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  PropertyDecls(0), NumPropertyDecls(-1), PropertyAttributes(OBJC_PR_noattr),
81082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  GetterName(0), SetterName(0) {}
81182a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
81282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  ObjcIvarDecl **const getPropertyDecls() const { return PropertyDecls; }
81382a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  void setPropertyDecls(ObjcIvarDecl **property) { PropertyDecls = property; }
81482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
81582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  const int getNumPropertyDecls() const { return NumPropertyDecls; }
81682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  void setNumPropertyDecls(int num) { NumPropertyDecls = num; }
81782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
818564576b225386cbff375351597dd5e2a92872d38Fariborz Jahanian  const PropertyAttributeKind getPropertyAttributes() const
81982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian    { return PropertyAttributes; }
820564576b225386cbff375351597dd5e2a92872d38Fariborz Jahanian  void setPropertyAttributes(PropertyAttributeKind PRVal) {
82182a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian    PropertyAttributes =
822564576b225386cbff375351597dd5e2a92872d38Fariborz Jahanian    (PropertyAttributeKind) (PropertyAttributes | PRVal);
82382a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  }
82482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
82582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  const IdentifierInfo *getGetterName() const { return GetterName; }
82682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  IdentifierInfo *getGetterName() { return GetterName; }
82782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  void setGetterName(IdentifierInfo *Id) { GetterName = Id; }
82882a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
82982a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  const IdentifierInfo *getSetterName() const { return SetterName; }
83082a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  IdentifierInfo *getSetterName() { return SetterName; }
83182a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  void setSetterName(IdentifierInfo *Id) { SetterName = Id; }
83282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian
83382a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  static bool classof(const Decl *D) {
83482a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian    return D->getKind() == PropertyDecl;
83582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  }
83682a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  static bool classof(const ObjcPropertyDecl *D) { return true; }
83782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian};
838980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
839980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff}  // end namespace clang
840980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff#endif
841