DeclObjC.h revision 321c22f1c4271c3d9a3d4d3fc18847f948ab595b
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"
186ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson#include "llvm/ADT/STLExtras.h"
19980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
20980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffnamespace clang {
21980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass Expr;
22980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass Stmt;
23980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass FunctionDecl;
24980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass AttributeList;
2560f8c868ffb346b78451a3eccaecd0461d2ae498Fariborz Jahanianclass RecordDecl;
26a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCIvarDecl;
27a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCMethodDecl;
28a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCProtocolDecl;
29a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCCategoryDecl;
30a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCPropertyDecl;
31f624f8186d8fe474350051c6d3f00b2c204fbeaeFariborz Jahanianclass ObjCPropertyImplDecl;
3268835718c4125f2f66740cd04de7088645ec695dChris Lattner
33793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattnerclass ObjCListBase {
34793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  void operator=(const ObjCListBase &);     // DO NOT IMPLEMENT
35793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  ObjCListBase(const ObjCListBase&);        // DO NOT IMPLEMENT
36793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattnerprotected:
37793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  /// List is an array of pointers to objects that are not owned by this object.
38793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  void **List;
393db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  unsigned NumElts;
40793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner
413db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattnerpublic:
42793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  ObjCListBase() : List(0), NumElts(0) {}
43793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  ~ObjCListBase() {
4488cf7a16902a9189d16653e1061cfda333187b58Chris Lattner    assert(List == 0 && "Destroy should have been called before dtor");
453db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  }
461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4738af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  void Destroy(ASTContext &Ctx);
481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
49793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  unsigned size() const { return NumElts; }
50793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  bool empty() const { return NumElts == 0; }
511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
52793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattnerprotected:
5338af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  void set(void *const* InList, unsigned Elts, ASTContext &Ctx);
54793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner};
551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
57793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner/// ObjCList - This is a simple template class used to hold various lists of
58793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner/// decls etc, which is heavily used by the ObjC front-end.  This only use case
59793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner/// this supports is setting the list all at once and then reading elements out
60793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner/// of it.
61793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattnertemplate <typename T>
62793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattnerclass ObjCList : public ObjCListBase {
63793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattnerpublic:
6438af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  void set(T* const* InList, unsigned Elts, ASTContext &Ctx) {
6538af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner    ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx);
66793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  }
671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
68793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  typedef T* const * iterator;
69793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  iterator begin() const { return (iterator)List; }
70793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  iterator end() const { return (iterator)List+NumElts; }
711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
72793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  T* operator[](unsigned Idx) const {
73793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner    assert(Idx < NumElts && "Invalid access");
74793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner    return (T*)List[Idx];
753db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  }
763db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner};
773db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner
781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
80a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCMethodDecl - Represents an instance or class method declaration.
8158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// ObjC methods can be declared within 4 contexts: class interfaces,
8258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// categories, protocols, and class implementations. While C++ member
831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// functions leverage C syntax, Objective-C method syntax is modeled after
841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// Smalltalk (using colons to specify argument types/expressions).
8558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// Here are some brief examples:
8658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff///
8758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// Setter/getter instance methods:
8858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// - (void)setMenu:(NSMenu *)menu;
891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// - (NSMenu *)menu;
901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
9158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// Instance method that takes 2 NSView arguments:
9258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
9358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff///
9458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// Getter class method:
9558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// + (NSMenu *)defaultMenu;
9658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff///
9758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// A selector represents a unique name for a method. The selector names for
9858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
9958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff///
1004afa39deaa245592977136d367251ee2c173dd8dDouglas Gregorclass ObjCMethodDecl : public NamedDecl, public DeclContext {
10158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroffpublic:
10258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  enum ImplementationControl { None, Required, Optional };
10358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroffprivate:
10458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// Bitfields must be first fields in this class so they pack with those
10558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// declared in class Decl.
10658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// instance (true) or class (false) method.
10758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  bool IsInstance : 1;
10858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  bool IsVariadic : 1;
1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1104607034e621aa77378ec75249d1e9eaf5de49b6aFariborz Jahanian  // Synthesized declaration method for a property setter/getter
1114607034e621aa77378ec75249d1e9eaf5de49b6aFariborz Jahanian  bool IsSynthesized : 1;
1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
113ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
11458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// @required/@optional
115ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  unsigned DeclImplementation : 2;
1161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
117ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
11858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// in, inout, etc.
119ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  unsigned objcDeclQualifier : 6;
1201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Type of this method.
12258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  QualType MethodDeclType;
1232073216a1075767b5d25c23d1462b7034686d94dChris Lattner  /// ParamInfo - List of pointers to VarDecls for the formal parameters of this
1242073216a1075767b5d25c23d1462b7034686d94dChris Lattner  /// Method.
1252073216a1075767b5d25c23d1462b7034686d94dChris Lattner  ObjCList<ParmVarDecl> ParamInfo;
1261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// List of attributes for this method declaration.
128a2e85ada1dfef36201a31f6646bc4ea3bd76a89aArgyrios Kyrtzidis  SourceLocation EndLoc; // the location of the ';' or '}'.
1291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // The following are only used for method definitions, null otherwise.
13158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // FIXME: space savings opportunity, consider a sub-class.
13258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  Stmt *Body;
133451318c08a6342c10b8986060386fd9274418437Daniel Dunbar
134451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  /// SelfDecl - Decl for the implicit self parameter. This is lazily
135451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  /// constructed by createImplicitParams.
1364111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  ImplicitParamDecl *SelfDecl;
137451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily
138451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  /// constructed by createImplicitParams.
1394111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  ImplicitParamDecl *CmdDecl;
1401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
141a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
14258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff                 Selector SelInfo, QualType T,
1430701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff                 DeclContext *contextDecl,
144f6414927e67e27d9324d8d179c5f7ea620443924Daniel Dunbar                 bool isInstance = true,
14558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff                 bool isVariadic = false,
1464607034e621aa77378ec75249d1e9eaf5de49b6aFariborz Jahanian                 bool isSynthesized = false,
14758cce3b0dcbdcc95b7e713795834b4cb2c8a008aChris Lattner                 ImplementationControl impControl = None)
1484afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
149b048c9835969c4f7fe06264748be18ed4b442116Chris Lattner    DeclContext(ObjCMethod),
15058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    IsInstance(isInstance), IsVariadic(isVariadic),
1514607034e621aa77378ec75249d1e9eaf5de49b6aFariborz Jahanian    IsSynthesized(isSynthesized),
15258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff    DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
1531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    MethodDeclType(T),
1544111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {}
1558a779314870760848e61da2c428a78971fe3f1c3Ted Kremenek
1562073216a1075767b5d25c23d1462b7034686d94dChris Lattner  virtual ~ObjCMethodDecl() {}
15757ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis
15857ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis  /// \brief A definition will return its interface declaration.
15957ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis  /// An interface declaration will return its definition.
16057ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis  /// Otherwise it will return itself.
16157ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis  virtual ObjCMethodDecl *getNextRedeclaration();
16257ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis
1636c4ae5de0c356777446f823b573821fb95560d91Chris Lattnerpublic:
1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1658a779314870760848e61da2c428a78971fe3f1c3Ted Kremenek  /// Destroy - Call destructors and release memory.
1668a779314870760848e61da2c428a78971fe3f1c3Ted Kremenek  virtual void Destroy(ASTContext& C);
1676c4ae5de0c356777446f823b573821fb95560d91Chris Lattner
1680ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner  static ObjCMethodDecl *Create(ASTContext &C,
1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                SourceLocation beginLoc,
1706c4ae5de0c356777446f823b573821fb95560d91Chris Lattner                                SourceLocation endLoc, Selector SelInfo,
1710701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff                                QualType T, DeclContext *contextDecl,
172f6414927e67e27d9324d8d179c5f7ea620443924Daniel Dunbar                                bool isInstance = true,
1736c4ae5de0c356777446f823b573821fb95560d91Chris Lattner                                bool isVariadic = false,
1744607034e621aa77378ec75249d1e9eaf5de49b6aFariborz Jahanian                                bool isSynthesized = false,
175b06fa3b86951b9f179c99c3768331536c32e902dChris Lattner                                ImplementationControl impControl = None);
176e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis
177e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis  virtual ObjCMethodDecl *getCanonicalDecl();
178e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis
179ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  ObjCDeclQualifier getObjCDeclQualifier() const {
180ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek    return ObjCDeclQualifier(objcDeclQualifier);
181ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  }
182a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Location information, modeled after the Stmt API.
18558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  SourceLocation getLocStart() const { return getLocation(); }
18658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
18753c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff  void setEndLoc(SourceLocation Loc) { EndLoc = Loc; }
1881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual SourceRange getSourceRange() const {
1891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return SourceRange(getLocation(), EndLoc);
1909776ba0d844cf9f6888e871e3fd246ae782f76f4Daniel Dunbar  }
1911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1925619688510185081cbb4621d703daf7ee24cf39aChris Lattner  ObjCInterfaceDecl *getClassInterface();
1935619688510185081cbb4621d703daf7ee24cf39aChris Lattner  const ObjCInterfaceDecl *getClassInterface() const {
1945619688510185081cbb4621d703daf7ee24cf39aChris Lattner    return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
195e0def7589a8afa8a6acef13476bb3f882c104b91Chris Lattner  }
1961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1972e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  Selector getSelector() const { return getDeclName().getObjCSelector(); }
1983a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson
19958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  QualType getResultType() const { return MethodDeclType; }
20053c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff  void setResultType(QualType T) { MethodDeclType = T; }
2011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
202d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  // Iterator access to formal parameters.
2032073216a1075767b5d25c23d1462b7034686d94dChris Lattner  unsigned param_size() const { return ParamInfo.size(); }
2042073216a1075767b5d25c23d1462b7034686d94dChris Lattner  typedef ObjCList<ParmVarDecl>::iterator param_iterator;
2052073216a1075767b5d25c23d1462b7034686d94dChris Lattner  param_iterator param_begin() const { return ParamInfo.begin(); }
2062073216a1075767b5d25c23d1462b7034686d94dChris Lattner  param_iterator param_end() const { return ParamInfo.end(); }
20789951a86b594513c2a013532ed45d197413b1087Chris Lattner
20853c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff  void setMethodParams(ASTContext &C, ParmVarDecl *const *List, unsigned Num) {
20938af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner    ParamInfo.set(List, Num, C);
2102073216a1075767b5d25c23d1462b7034686d94dChris Lattner  }
2114111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
2126ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson  // Iterator access to parameter types.
2136ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson  typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
2146ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson  typedef llvm::mapped_iterator<param_iterator, deref_fun> arg_type_iterator;
2156ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson
2166ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson  arg_type_iterator arg_type_begin() const {
2176ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson    return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
2186ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson  }
2196ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson  arg_type_iterator arg_type_end() const {
2206ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson    return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType));
2216ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson  }
2221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
223451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  /// createImplicitParams - Used to lazily create the self and cmd
224451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  /// implict parameters. This must be called prior to using getSelfDecl()
225451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  /// or getCmdDecl(). The call is ignored if the implicit paramters
226451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  /// have already been created.
227fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanian  void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
228451318c08a6342c10b8986060386fd9274418437Daniel Dunbar
2294111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
23053c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff  void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; }
2314111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
23253c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff  void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; }
2331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
234f8d49f64ef6ab7e632717a31631fc289aab69428Douglas Gregor  bool isInstanceMethod() const { return IsInstance; }
23553c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff  void setInstanceMethod(bool isInst) { IsInstance = isInst; }
23658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  bool isVariadic() const { return IsVariadic; }
23753c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff  void setVariadic(bool isVar) { IsVariadic = isVar; }
2381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
239f8d49f64ef6ab7e632717a31631fc289aab69428Douglas Gregor  bool isClassMethod() const { return !IsInstance; }
240f8d49f64ef6ab7e632717a31631fc289aab69428Douglas Gregor
2414607034e621aa77378ec75249d1e9eaf5de49b6aFariborz Jahanian  bool isSynthesized() const { return IsSynthesized; }
24253c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff  void setSynthesized(bool isSynth) { IsSynthesized = isSynth; }
2431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Related to protocols declared in  @protocol
2451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  void setDeclImplementation(ImplementationControl ic) {
2461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    DeclImplementation = ic;
24758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
2481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ImplementationControl getImplementationControl() const {
2491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return ImplementationControl(DeclImplementation);
25058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
251792481eec23d8c1aa92173be589e2ae9d02514a5Ted Kremenek
2521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual Stmt *getBody() const {
2531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return (Stmt*) Body;
2547297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor  }
2556fb0aee4f9dc261bbec72e1283ad8dc0557a6d96Argyrios Kyrtzidis  CompoundStmt *getCompoundBody() { return (CompoundStmt*)Body; }
256d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  void setBody(Stmt *B) { Body = B; }
25758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
25866570b230941651245accbc5680b60e904eb993cArgyrios Kyrtzidis  /// \brief Returns whether this specific method is a definition.
25966570b230941651245accbc5680b60e904eb993cArgyrios Kyrtzidis  bool isThisDeclarationADefinition() const { return Body; }
26066570b230941651245accbc5680b60e904eb993cArgyrios Kyrtzidis
26158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Implement isa/cast/dyncast/etc.
262a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCMethod; }
263a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCMethodDecl *D) { return true; }
26442220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis  static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
26542220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis    return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
26642220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis  }
26742220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis  static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) {
26842220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis    return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC));
26942220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis  }
27058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff};
271e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff
272f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor/// ObjCMethodList - a linked list of methods with different signatures.
273f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregorstruct ObjCMethodList {
274f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor  ObjCMethodDecl *Method;
275f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor  ObjCMethodList *Next;
2761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
277f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor  ObjCMethodList() {
2781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Method = 0;
279f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor    Next = 0;
280f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor  }
281f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor  ObjCMethodList(ObjCMethodDecl *M, ObjCMethodList *C) {
282f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor    Method = M;
283f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor    Next = C;
284f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor  }
285f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor};
286f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor
287e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff/// ObjCContainerDecl - Represents a container for method declarations.
288aecae629269fae3bf484baf1d109e9a89d14eeadArgyrios Kyrtzidis/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
2891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ObjCProtocolDecl, and ObjCImplDecl.
290e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff///
2914afa39deaa245592977136d367251ee2c173dd8dDouglas Gregorclass ObjCContainerDecl : public NamedDecl, public DeclContext {
292e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff  SourceLocation AtEndLoc; // marks the end of the method container.
293e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroffpublic:
294e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff
2951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ObjCContainerDecl(Kind DK, DeclContext *DC, SourceLocation L,
296d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor                    IdentifierInfo *Id)
2974afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    : NamedDecl(DK, DC, L, Id), DeclContext(DK) {}
298e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff
2990b7ebb3dba0df0a6cbf221e5edbc6a4b8848478cChris Lattner  virtual ~ObjCContainerDecl() {}
30009c4719788a5cea09897525e528fa00420f1677bSteve Naroff
30193983f8fa120330bf212bfde7e65da2709fb3be8Steve Naroff  // Iterator access to properties.
30293983f8fa120330bf212bfde7e65da2709fb3be8Steve Naroff  typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
3031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  prop_iterator prop_begin() const {
30417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return prop_iterator(decls_begin());
30593983f8fa120330bf212bfde7e65da2709fb3be8Steve Naroff  }
3061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  prop_iterator prop_end() const {
30717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return prop_iterator(decls_end());
30809c4719788a5cea09897525e528fa00420f1677bSteve Naroff  }
3091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3100701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  // Iterator access to instance/class methods.
311f8d49f64ef6ab7e632717a31631fc289aab69428Douglas Gregor  typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  method_iterator meth_begin() const {
31317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return method_iterator(decls_begin());
3147ed4faca5162b3ab85be7f7e57aa40e6ec170971Ted Kremenek  }
3151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  method_iterator meth_end() const {
31617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return method_iterator(decls_end());
3177ed4faca5162b3ab85be7f7e57aa40e6ec170971Ted Kremenek  }
3180701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff
3191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  typedef filtered_decl_iterator<ObjCMethodDecl,
3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                 &ObjCMethodDecl::isInstanceMethod>
321669c9a28fa4be35e6b6322aa7f2f3b2968189b80Douglas Gregor    instmeth_iterator;
32217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  instmeth_iterator instmeth_begin() const {
32317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return instmeth_iterator(decls_begin());
324e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff  }
32517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  instmeth_iterator instmeth_end() const {
32617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return instmeth_iterator(decls_end());
327e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff  }
328e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff
3291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  typedef filtered_decl_iterator<ObjCMethodDecl,
3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                 &ObjCMethodDecl::isClassMethod>
331669c9a28fa4be35e6b6322aa7f2f3b2968189b80Douglas Gregor    classmeth_iterator;
33217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  classmeth_iterator classmeth_begin() const {
33317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return classmeth_iterator(decls_begin());
334e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff  }
33517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  classmeth_iterator classmeth_end() const {
33617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return classmeth_iterator(decls_end());
3370701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  }
3380701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff
3390701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  // Get the local instance/class method declared in this interface.
340467c0b165072689ef87fe8d9cd47a5b63485bcdcArgyrios Kyrtzidis  ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const;
341467c0b165072689ef87fe8d9cd47a5b63485bcdcArgyrios Kyrtzidis  ObjCMethodDecl *getInstanceMethod(Selector Sel) const {
342467c0b165072689ef87fe8d9cd47a5b63485bcdcArgyrios Kyrtzidis    return getMethod(Sel, true/*isInstance*/);
34353df12d1ba68dbd071d067f8236c16fba815aad5Chris Lattner  }
344467c0b165072689ef87fe8d9cd47a5b63485bcdcArgyrios Kyrtzidis  ObjCMethodDecl *getClassMethod(Selector Sel) const {
345467c0b165072689ef87fe8d9cd47a5b63485bcdcArgyrios Kyrtzidis    return getMethod(Sel, false/*isInstance*/);
346467c0b165072689ef87fe8d9cd47a5b63485bcdcArgyrios Kyrtzidis  }
347467c0b165072689ef87fe8d9cd47a5b63485bcdcArgyrios Kyrtzidis  ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
3481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
34917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
350a6f14e1a7ee3a9343a838297c73ca87fddb9ed4aFariborz Jahanian  ObjCPropertyDecl *FindPropertyVisibleInPrimaryClass(
351a6f14e1a7ee3a9343a838297c73ca87fddb9ed4aFariborz Jahanian                                            IdentifierInfo *PropertyId) const;
35293983f8fa120330bf212bfde7e65da2709fb3be8Steve Naroff
353e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff  // Marks the end of the container.
354e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff  SourceLocation getAtEndLoc() const { return AtEndLoc; }
3550701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  void setAtEndLoc(SourceLocation L) { AtEndLoc = L; }
356ddfd4c9eda34765b08fae4cb31ad5a365face107Argyrios Kyrtzidis
357ddfd4c9eda34765b08fae4cb31ad5a365face107Argyrios Kyrtzidis  virtual SourceRange getSourceRange() const {
358ddfd4c9eda34765b08fae4cb31ad5a365face107Argyrios Kyrtzidis    return SourceRange(getLocation(), getAtEndLoc());
359ddfd4c9eda34765b08fae4cb31ad5a365face107Argyrios Kyrtzidis  }
3601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
36109c4719788a5cea09897525e528fa00420f1677bSteve Naroff  // Implement isa/cast/dyncast/etc.
36209c4719788a5cea09897525e528fa00420f1677bSteve Naroff  static bool classof(const Decl *D) {
3631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return D->getKind() >= ObjCContainerFirst &&
36409c4719788a5cea09897525e528fa00420f1677bSteve Naroff           D->getKind() <= ObjCContainerLast;
36509c4719788a5cea09897525e528fa00420f1677bSteve Naroff  }
36609c4719788a5cea09897525e528fa00420f1677bSteve Naroff  static bool classof(const ObjCContainerDecl *D) { return true; }
36709c4719788a5cea09897525e528fa00420f1677bSteve Naroff
36809c4719788a5cea09897525e528fa00420f1677bSteve Naroff  static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
36909c4719788a5cea09897525e528fa00420f1677bSteve Naroff    return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
37009c4719788a5cea09897525e528fa00420f1677bSteve Naroff  }
37109c4719788a5cea09897525e528fa00420f1677bSteve Naroff  static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) {
37209c4719788a5cea09897525e528fa00420f1677bSteve Naroff    return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC));
37309c4719788a5cea09897525e528fa00420f1677bSteve Naroff  }
374e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff};
375e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff
376a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCInterfaceDecl - Represents an ObjC class declaration. For example:
3770c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
3780c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   // MostPrimitive declares no super class (not particularly useful).
3791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///   @interface MostPrimitive
3800c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     // no instance variables or methods.
3810c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @end
3820c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///   // NSResponder inherits from NSObject & implements NSCoding (a protocol).
3840c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @interface NSResponder : NSObject <NSCoding>
385a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek///   { // instance variables are represented by ObjCIvarDecl.
3860c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id nextResponder; // nextResponder instance variable.
3870c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   }
3880c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   - (NSResponder *)nextResponder; // return a pointer to NSResponder.
3890c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
3900c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @end                                    // to an NSEvent.
3910c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
3920c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   Unlike C/C++, forward class declarations are accomplished with @class.
3930c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   Unlike C/C++, @class allows for a list of classes to be forward declared.
3940c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
3950c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   typically inherit from NSObject (an exception is NSProxy).
3960c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
3970701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroffclass ObjCInterfaceDecl : public ObjCContainerDecl {
3983110251f13981689f384eb3c0aba2afffea18d9dSteve Naroff  /// TypeForDecl - This indicates the Type object that represents this
3993110251f13981689f384eb3c0aba2afffea18d9dSteve Naroff  /// TypeDecl.  It is a cache maintained by ASTContext::getObjCInterfaceType
4003b3a45858c6b2a45114e91902c3bf3c4b7f5f302Daniel Dunbar  mutable Type *TypeForDecl;
4013110251f13981689f384eb3c0aba2afffea18d9dSteve Naroff  friend class ASTContext;
4021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
403980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Class's super class.
404a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *SuperClass;
4051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
406980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Protocols referenced in interface header declaration
4073db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  ObjCList<ObjCProtocolDecl> ReferencedProtocols;
4081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
409e881483a3bc22ffad62367501aa09ad8508fe363Chris Lattner  /// Instance variables in the interface.
410e881483a3bc22ffad62367501aa09ad8508fe363Chris Lattner  ObjCList<ObjCIvarDecl> IVars;
4111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
412980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// List of categories defined for this class.
413a8ff9f455d94d9609766cfd5186b6e21dc2102f1Chris Lattner  /// FIXME: Why is this a linked list??
414a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryDecl *CategoryList;
4151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4163a3ca1b35a7121aea0bf465a192dce748465e10fFariborz Jahanian  bool ForwardDecl:1; // declared with @class.
4173a3ca1b35a7121aea0bf465a192dce748465e10fFariborz Jahanian  bool InternalInterface:1; // true - no @interface for @implementation
4181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
419d6a07aaf62b40cdfbd96f6b874d02b06fc22d015Steve Naroff  SourceLocation ClassLoc; // location of the class identifier.
420d6a07aaf62b40cdfbd96f6b874d02b06fc22d015Steve Naroff  SourceLocation SuperClassLoc; // location of the super class identifier.
421f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  SourceLocation EndLoc; // marks the '>', '}', or identifier.
4220e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner
423d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
4240b7ebb3dba0df0a6cbf221e5edbc6a4b8848478cChris Lattner                    SourceLocation CLoc, bool FD, bool isInternal);
4251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
426e881483a3bc22ffad62367501aa09ad8508fe363Chris Lattner  virtual ~ObjCInterfaceDecl() {}
4271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4280e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattnerpublic:
4290e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner
4308a779314870760848e61da2c428a78971fe3f1c3Ted Kremenek  /// Destroy - Call destructors and release memory.
4318a779314870760848e61da2c428a78971fe3f1c3Ted Kremenek  virtual void Destroy(ASTContext& C);
4328a779314870760848e61da2c428a78971fe3f1c3Ted Kremenek
433d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  static ObjCInterfaceDecl *Create(ASTContext &C, DeclContext *DC,
4340ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner                                   SourceLocation atLoc,
4351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                   IdentifierInfo *Id,
436d6a07aaf62b40cdfbd96f6b874d02b06fc22d015Steve Naroff                                   SourceLocation ClassLoc = SourceLocation(),
4370e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner                                   bool ForwardDecl = false,
4380e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner                                   bool isInternal = false);
4391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const {
4401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return ReferencedProtocols;
4417ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  }
4428a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
4438a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  ObjCImplementationDecl *getImplementation() const;
4448a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  void setImplementation(ObjCImplementationDecl *ImplD);
4458a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
446559c0c4bbecc017aab0716d546c4fefbcc194687Fariborz Jahanian  ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
4471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4481cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis  // Get the local instance/class method declared in a category.
4491cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis  ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const;
4501cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis  ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const;
4511cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis  ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const {
4521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return isInstance ? getInstanceMethod(Sel)
4531cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis                      : getClassMethod(Sel);
4541cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis  }
4553db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner
4563db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator;
4573db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
4583db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
459291be393aa33759e6e34b6429c5ffa206ba50115Douglas Gregor  unsigned protocol_size() const { return ReferencedProtocols.size(); }
460291be393aa33759e6e34b6429c5ffa206ba50115Douglas Gregor
461e881483a3bc22ffad62367501aa09ad8508fe363Chris Lattner  typedef ObjCList<ObjCIvarDecl>::iterator ivar_iterator;
462e881483a3bc22ffad62367501aa09ad8508fe363Chris Lattner  ivar_iterator ivar_begin() const { return IVars.begin(); }
463e881483a3bc22ffad62367501aa09ad8508fe363Chris Lattner  ivar_iterator ivar_end() const { return IVars.end(); }
464e881483a3bc22ffad62367501aa09ad8508fe363Chris Lattner  unsigned ivar_size() const { return IVars.size(); }
465e881483a3bc22ffad62367501aa09ad8508fe363Chris Lattner  bool ivar_empty() const { return IVars.empty(); }
4661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
46738af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  /// setProtocolList - Set the list of protocols that this interface
468b752f289026ad8e5f44851b20e009a27ed61eefcChris Lattner  /// implements.
46938af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
47038af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner                       ASTContext &C) {
47138af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner    ReferencedProtocols.set(List, Num, C);
4723db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  }
4731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
474339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian  /// mergeClassExtensionProtocolList - Merge class extension's protocol list
475339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian  /// into the protocol list for this class.
476339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian  void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
477339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian                       ASTContext &C);
478339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian
47938af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  void setIVarList(ObjCIvarDecl * const *List, unsigned Num, ASTContext &C) {
48038af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner    IVars.set(List, Num, C);
481e881483a3bc22ffad62367501aa09ad8508fe363Chris Lattner  }
482980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
483768f26ee5892cd63ff0335a15d71a2385ba7c5eaSteve Naroff  bool isForwardDecl() const { return ForwardDecl; }
484768f26ee5892cd63ff0335a15d71a2385ba7c5eaSteve Naroff  void setForwardDecl(bool val) { ForwardDecl = val; }
4851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
486a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
487a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
4881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
489a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryDecl* getCategoryList() const { return CategoryList; }
4901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  void setCategoryList(ObjCCategoryDecl *category) {
49153efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner    CategoryList = category;
492980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
4931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
49453efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner  /// isSuperClassOf - Return true if this class is the specified class or is a
49553efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner  /// super class of the specified interface class.
49653efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner  bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
49753efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner    // If RHS is derived from LHS it is OK; else it is not OK.
49853efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner    while (I != NULL) {
49953efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner      if (this == I)
50053efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner        return true;
50153efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner      I = I->getSuperClass();
50253efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner    }
50353efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner    return false;
50453efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner  }
5051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
50617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
50768a057b4292f5ff814ec8da53f6cda8cdcfbd2aeChris Lattner                                       ObjCInterfaceDecl *&ClassDeclared);
50817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
50968a057b4292f5ff814ec8da53f6cda8cdcfbd2aeChris Lattner    ObjCInterfaceDecl *ClassDeclared;
51017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return lookupInstanceVariable(IVarName, ClassDeclared);
51168a057b4292f5ff814ec8da53f6cda8cdcfbd2aeChris Lattner  }
51268a057b4292f5ff814ec8da53f6cda8cdcfbd2aeChris Lattner
51394a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // Lookup a method. First, we search locally. If a method isn't
51494a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // found, we search referenced protocols and class categories.
515aa5420c1e36ab8e0e4bb87239d8b73a3a8ce75dbArgyrios Kyrtzidis  ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const;
516aa5420c1e36ab8e0e4bb87239d8b73a3a8ce75dbArgyrios Kyrtzidis  ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
517aa5420c1e36ab8e0e4bb87239d8b73a3a8ce75dbArgyrios Kyrtzidis    return lookupMethod(Sel, true/*isInstance*/);
518aa5420c1e36ab8e0e4bb87239d8b73a3a8ce75dbArgyrios Kyrtzidis  }
519aa5420c1e36ab8e0e4bb87239d8b73a3a8ce75dbArgyrios Kyrtzidis  ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
520aa5420c1e36ab8e0e4bb87239d8b73a3a8ce75dbArgyrios Kyrtzidis    return lookupMethod(Sel, false/*isInstance*/);
521aa5420c1e36ab8e0e4bb87239d8b73a3a8ce75dbArgyrios Kyrtzidis  }
522cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian  ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
523d789d3d985e28c9404e62157af46dcb7331920e0Steve Naroff
524d789d3d985e28c9404e62157af46dcb7331920e0Steve Naroff  // Lookup a method in the classes implementation hierarchy.
525d789d3d985e28c9404e62157af46dcb7331920e0Steve Naroff  ObjCMethodDecl *lookupPrivateInstanceMethod(const Selector &Sel);
52660fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff
527ddfd4c9eda34765b08fae4cb31ad5a365face107Argyrios Kyrtzidis  // Location information, modeled after the Stmt API.
52860fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff  SourceLocation getLocStart() const { return getLocation(); } // '@'interface
529f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
530f908a87299d278164540f90b5b6e6cab7b14fb41Steve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
5311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
53233feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff  void setClassLoc(SourceLocation Loc) { ClassLoc = Loc; }
533d6a07aaf62b40cdfbd96f6b874d02b06fc22d015Steve Naroff  SourceLocation getClassLoc() const { return ClassLoc; }
534d6a07aaf62b40cdfbd96f6b874d02b06fc22d015Steve Naroff  void setSuperClassLoc(SourceLocation Loc) { SuperClassLoc = Loc; }
535d6a07aaf62b40cdfbd96f6b874d02b06fc22d015Steve Naroff  SourceLocation getSuperClassLoc() const { return SuperClassLoc; }
5361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
53728e71cf851b73a67604735a9a95aef800b144e2eSteve Naroff  /// isImplicitInterfaceDecl - check that this is an implicitly declared
538a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  /// ObjCInterfaceDecl node. This is for legacy objective-c @implementation
5394b6df3fa953267c5d755628c8afd818bb571e579Fariborz Jahanian  /// declaration without an @interface declaration.
54033feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff  bool isImplicitInterfaceDecl() const { return InternalInterface; }
54133feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff  void setImplicitInterfaceDecl(bool val) { InternalInterface = val; }
5421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5430fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  /// ClassImplementsProtocol - Checks that 'lProto' protocol
5440fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  /// has been implemented in IDecl class, its super class or categories (if
5450fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  /// lookupCategory is true).
5460fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
5470fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian                               bool lookupCategory,
5480fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian                               bool RHSIsQualifiedID = false);
5491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
55033feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff  // Low-level accessor
55133feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff  Type *getTypeForDecl() const { return TypeForDecl; }
5523b3a45858c6b2a45114e91902c3bf3c4b7f5f302Daniel Dunbar  void setTypeForDecl(Type *TD) const { TypeForDecl = TD; }
55333feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff
554a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCInterface; }
555a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCInterfaceDecl *D) { return true; }
556980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
557980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
558a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
5590c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// instance variables are identical to C. The only exception is Objective-C
5600c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// supports C++ style access control. For example:
5610c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
5620c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @interface IvarExample : NSObject
5630c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   {
564f079570fcad0d0053e75ebae29c883ec4276e020Ted Kremenek///     id defaultToProtected;
5650c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @public:
5660c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id canBePublic; // same as C++.
5670c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @protected:
5680c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id canBeProtected; // same as C++.
5690c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   @package:
5700c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id canBePackage; // framework visibility (not available in C++).
5710c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   }
5720c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
573a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCIvarDecl : public FieldDecl {
5740e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattnerpublic:
575980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  enum AccessControl {
576980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    None, Private, Protected, Public, Package
577980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  };
5781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
579b8db21d4df5fbb6ce1ace6411b82d3d623d789deTed Kremenekprivate:
5800c00aac5d618f39afc406c5b2e07642930af1d56Argyrios Kyrtzidis  ObjCIvarDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
581a1d5662d96465f0fddf8819d245da4d19b892effArgyrios Kyrtzidis               QualType T, DeclaratorInfo *DInfo, AccessControl ac, Expr *BW)
5821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : FieldDecl(ObjCIvar, DC, L, Id, T, DInfo, BW, /*Mutable=*/false),
58344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      DeclAccess(ac) {}
5841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
585b8db21d4df5fbb6ce1ace6411b82d3d623d789deTed Kremenekpublic:
5860c00aac5d618f39afc406c5b2e07642930af1d56Argyrios Kyrtzidis  static ObjCIvarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
587b8db21d4df5fbb6ce1ace6411b82d3d623d789deTed Kremenek                              IdentifierInfo *Id, QualType T,
588a1d5662d96465f0fddf8819d245da4d19b892effArgyrios Kyrtzidis                              DeclaratorInfo *DInfo,
589b8db21d4df5fbb6ce1ace6411b82d3d623d789deTed Kremenek                              AccessControl ac, Expr *BW = NULL);
5901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
591980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void setAccessControl(AccessControl ac) { DeclAccess = ac; }
592f079570fcad0d0053e75ebae29c883ec4276e020Ted Kremenek
593ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
594f079570fcad0d0053e75ebae29c883ec4276e020Ted Kremenek
595f079570fcad0d0053e75ebae29c883ec4276e020Ted Kremenek  AccessControl getCanonicalAccessControl() const {
596f079570fcad0d0053e75ebae29c883ec4276e020Ted Kremenek    return DeclAccess == None ? Protected : AccessControl(DeclAccess);
597f079570fcad0d0053e75ebae29c883ec4276e020Ted Kremenek  }
5981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
599980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  // Implement isa/cast/dyncast/etc.
600a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCIvar; }
601a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCIvarDecl *D) { return true; }
602980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffprivate:
603ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
604ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  unsigned DeclAccess : 3;
605980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
606980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
6071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60801e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek/// ObjCAtDefsFieldDecl - Represents a field declaration created by an
60901e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek///  @defs(...).
61001e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenekclass ObjCAtDefsFieldDecl : public FieldDecl {
61101e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenekprivate:
61244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
61301e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek                      QualType T, Expr *BW)
614a1d5662d96465f0fddf8819d245da4d19b892effArgyrios Kyrtzidis    : FieldDecl(ObjCAtDefsField, DC, L, Id, T,
615a1d5662d96465f0fddf8819d245da4d19b892effArgyrios Kyrtzidis                /*DInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ?
616a1d5662d96465f0fddf8819d245da4d19b892effArgyrios Kyrtzidis                BW, /*Mutable=*/false) {}
6171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61801e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenekpublic:
61944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
62044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor                                     SourceLocation L,
62101e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek                                     IdentifierInfo *Id, QualType T,
62201e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek                                     Expr *BW);
6231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62401e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek  virtual void Destroy(ASTContext& C);
62501e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek
62601e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek  // Implement isa/cast/dyncast/etc.
62701e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCAtDefsField; }
62801e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek  static bool classof(const ObjCAtDefsFieldDecl *D) { return true; }
62901e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek};
630980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
631a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols
6321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// declare a pure abstract type (i.e no instance variables are permitted).
6331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// Protocols orginally drew inspiration from C++ pure virtual functions (a C++
6340c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// feature with nice semantics and lousy syntax:-). Here is an example:
6350c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
636eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// @protocol NSDraggingInfo <refproto1, refproto2>
6370c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - (NSWindow *)draggingDestinationWindow;
6380c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - (NSImage *)draggedImage;
6390c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @end
6400c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
641eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// This says that NSDraggingInfo requires two methods and requires everything
642eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// that the two "referenced protocols" 'refproto1' and 'refproto2' require as
643eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// well.
644eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner///
6450c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @interface ImplementsNSDraggingInfo : NSObject <NSDraggingInfo>
6460c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @end
6470c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
648a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
6490c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// protocols are in distinct namespaces. For example, Cocoa defines both
6501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// an NSObject protocol and class (which isn't allowed in Java). As a result,
6510c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// protocols are referenced using angle brackets as follows:
6520c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
6530c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// id <NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
6540c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
655e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroffclass ObjCProtocolDecl : public ObjCContainerDecl {
656780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner  /// Referenced protocols
657780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner  ObjCList<ObjCProtocolDecl> ReferencedProtocols;
6581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
659980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  bool isForwardProtoDecl; // declared with @protocol.
6601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
661423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation EndLoc; // marks the '>' or identifier.
6621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
663d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  ObjCProtocolDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
6641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : ObjCContainerDecl(ObjCProtocol, DC, L, Id),
665c858105d41602a2dadb2efbc1af80a7b791ebac3Chris Lattner      isForwardProtoDecl(true) {
666cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner  }
6671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6684a323d94e50c8f570cbfaf0392e68215b8ca87bfChris Lattner  virtual ~ObjCProtocolDecl() {}
6691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
670cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattnerpublic:
6711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
672d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor                                  SourceLocation L, IdentifierInfo *Id);
673cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner
674411280e5b25ba7dcd7c8a82a5c23880fe7632a3cChris Lattner  /// Destroy - Call destructors and release memory.
675411280e5b25ba7dcd7c8a82a5c23880fe7632a3cChris Lattner  virtual void Destroy(ASTContext& C);
6761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const {
678780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner    return ReferencedProtocols;
679980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
680dbc933701d20918add13b6a3c9d47ff8c75419cfDaniel Dunbar  typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator;
681780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
682780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
68330833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff  unsigned protocol_size() const { return ReferencedProtocols.size(); }
6841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
68538af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  /// setProtocolList - Set the list of protocols that this interface
686780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner  /// implements.
68738af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
68838af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner                       ASTContext &C) {
68938af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner    ReferencedProtocols.set(List, Num, C);
690aebf0cba02c014ac8b19d615c654248e0e93779fFariborz Jahanian  }
6911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
69291b0b0cf6b537cbcbca0038c7032f87161a41d31Steve Naroff  ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName);
6931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
69494a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // Lookup a method. First, we search locally. If a method isn't
69594a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // found, we search referenced protocols and class categories.
696094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis  ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const;
697094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis  ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
698094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis    return lookupMethod(Sel, true/*isInstance*/);
699094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis  }
700094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis  ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
701094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis    return lookupMethod(Sel, false/*isInstance*/);
702094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis  }
703d789d3d985e28c9404e62157af46dcb7331920e0Steve Naroff
704768f26ee5892cd63ff0335a15d71a2385ba7c5eaSteve Naroff  bool isForwardDecl() const { return isForwardProtoDecl; }
705768f26ee5892cd63ff0335a15d71a2385ba7c5eaSteve Naroff  void setForwardDecl(bool val) { isForwardProtoDecl = val; }
706980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
7071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Location information, modeled after the Stmt API.
708423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getLocStart() const { return getLocation(); } // '@'protocol
709423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
710423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
7111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
712a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCProtocol; }
713a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCProtocolDecl *D) { return true; }
714980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
7151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
716a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCClassDecl - Specifies a list of forward class declarations. For example:
71706ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff///
71806ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff/// @class NSCursor, NSImage, NSPasteboard, NSWindow;
7190c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
7204afa39deaa245592977136d367251ee2c173dd8dDouglas Gregorclass ObjCClassDecl : public Decl {
721321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenekpublic:
722321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek  class ObjCClassRef {
723321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek    ObjCInterfaceDecl *ID;
724321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek    SourceLocation L;
725321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek  public:
726321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek    ObjCClassRef(ObjCInterfaceDecl *d, SourceLocation l) : ID(d), L(l) {}
727321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek    SourceLocation getLocation() const { return L; }
728321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek    ObjCInterfaceDecl *getInterface() const { return ID; }
729321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek  };
730321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenekprivate:
731321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek  ObjCClassRef *ForwardDecls;
732321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek  unsigned NumDecls;
7331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ObjCClassDecl(DeclContext *DC, SourceLocation L,
735321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek                ObjCInterfaceDecl *const *Elts, const SourceLocation *Locs,
736321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek                unsigned nElts, ASTContext &C);
73767956052ea5fb0cd7f443de96a11f9a0176dc681Chris Lattner  virtual ~ObjCClassDecl() {}
73861f9d41036e30ff80130f99b31c0626e3ef057ccChris Lattnerpublic:
7391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
740400d95fb7bb9fac609f8613862b84f3a2a7d510fTed Kremenek  /// Destroy - Call destructors and release memory.
741400d95fb7bb9fac609f8613862b84f3a2a7d510fTed Kremenek  virtual void Destroy(ASTContext& C);
7421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
743d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  static ObjCClassDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
7441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                               ObjCInterfaceDecl *const *Elts = 0,
745321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek                               const SourceLocation *Locs = 0,
74630833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff                               unsigned nElts = 0);
7471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
748321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek  typedef const ObjCClassRef* iterator;
749321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek  iterator begin() const { return ForwardDecls; }
750321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek  iterator end() const { return ForwardDecls + NumDecls; }
751321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek  unsigned size() const { return NumDecls; }
75230833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff
75330833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff  /// setClassList - Set the list of forward classes.
754321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek  void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List,
755321c22f1c4271c3d9a3d4d3fc18847f948ab595bTed Kremenek                    const SourceLocation *Locs, unsigned Num);
7561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
757a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCClass; }
758a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCClassDecl *D) { return true; }
75906ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff};
76006ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff
761a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations.
76206ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff/// For example:
7631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
7640c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo;
7651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
7664afa39deaa245592977136d367251ee2c173dd8dDouglas Gregorclass ObjCForwardProtocolDecl : public Decl {
76707fa7749da805969f2ed467a4eb5b405a4ff9a23Chris Lattner  ObjCList<ObjCProtocolDecl> ReferencedProtocols;
7681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
769d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
77038af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner                          ObjCProtocolDecl *const *Elts, unsigned nElts,
7711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                          ASTContext &C);
77207fa7749da805969f2ed467a4eb5b405a4ff9a23Chris Lattner  virtual ~ObjCForwardProtocolDecl() {}
7731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
77461f9d41036e30ff80130f99b31c0626e3ef057ccChris Lattnerpublic:
775d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC,
7761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                         SourceLocation L,
77730833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff                                         ObjCProtocolDecl *const *Elts = 0,
77830833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff                                         unsigned Num = 0);
77961f9d41036e30ff80130f99b31c0626e3ef057ccChris Lattner
7800b7ebb3dba0df0a6cbf221e5edbc6a4b8848478cChris Lattner  /// Destroy - Call destructors and release memory.
7810b7ebb3dba0df0a6cbf221e5edbc6a4b8848478cChris Lattner  virtual void Destroy(ASTContext& C);
7821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
78330833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff  typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator;
78430833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
78530833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
78630833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff  unsigned protocol_size() const { return ReferencedProtocols.size(); }
78730833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff
78830833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff  /// setProtocolList - Set the list of forward protocols.
78930833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff  void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
79030833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff                       ASTContext &C) {
79130833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff    ReferencedProtocols.set(List, Num, C);
79230833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff  }
79306ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  static bool classof(const Decl *D) {
794a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    return D->getKind() == ObjCForwardProtocol;
79506ae8d68ef258ccd40c9cd1ce762eaae6f3d4432Steve Naroff  }
796a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCForwardProtocolDecl *D) { return true; }
797980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
798980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
799a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCCategoryDecl - Represents a category declaration. A category allows
8000c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// you to add methods to an existing class (without subclassing or modifying
8011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// the original class interface or implementation:-). Categories don't allow
8020c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// you to add instance data. The following example adds "myMethod" to all
8030c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// NSView's within a process:
8040c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
8050c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @interface NSView (MyViewMethods)
8060c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - myMethod;
8070c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @end
8080c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
8090c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Cateogries also allow you to split the implementation of a class across
8100c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// several files (a feature more naturally supported in C++).
8110c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
8120c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Categories were originally inspired by dynamic languages such as Common
8131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// Lisp and Smalltalk.  More traditional class-based languages (C++, Java)
8140c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// don't support this level of dynamism, which is both powerful and dangerous.
8150c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
816e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroffclass ObjCCategoryDecl : public ObjCContainerDecl {
817980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Interface belonging to this category
818a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *ClassInterface;
8191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
82068c82cf61228102aba1194efef222fa1478af2a8Chris Lattner  /// referenced protocols in this category.
821780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner  ObjCList<ObjCProtocolDecl> ReferencedProtocols;
8221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
823a8ff9f455d94d9609766cfd5186b6e21dc2102f1Chris Lattner  /// Next category belonging to this class.
824a8ff9f455d94d9609766cfd5186b6e21dc2102f1Chris Lattner  /// FIXME: this should not be a singly-linked list.  Move storage elsewhere.
825a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryDecl *NextClassCategory;
8261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
827423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation EndLoc; // marks the '>' or identifier.
8281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
829d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  ObjCCategoryDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
830d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor    : ObjCContainerDecl(ObjCCategory, DC, L, Id),
8312f0fe337f499c78710b718324b25510670d885b1Chris Lattner      ClassInterface(0), NextClassCategory(0){
832a906135721c350435319347d2672bbb3bf494f91Chris Lattner  }
83361f9d41036e30ff80130f99b31c0626e3ef057ccChris Lattnerpublic:
8341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
835d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
8360ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner                                  SourceLocation L, IdentifierInfo *Id);
8371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
838e0def7589a8afa8a6acef13476bb3f882c104b91Chris Lattner  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
839e0def7589a8afa8a6acef13476bb3f882c104b91Chris Lattner  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
840a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; }
8418a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
8428a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  ObjCCategoryImplDecl *getImplementation() const;
8438a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  void setImplementation(ObjCCategoryImplDecl *ImplD);
8448a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
84538af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  /// setProtocolList - Set the list of protocols that this interface
846f7b2c98c16dfb2261ea57d40a1d5bc4738e73175Chris Lattner  /// implements.
84738af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
84838af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner                              ASTContext &C) {
84938af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner    ReferencedProtocols.set(List, Num, C);
850780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner  }
8511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const {
853780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner    return ReferencedProtocols;
8548f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian  }
8551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
856a8ff9f455d94d9609766cfd5186b6e21dc2102f1Chris Lattner  typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator;
857780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
858780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
85930833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff  unsigned protocol_size() const { return ReferencedProtocols.size(); }
8601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
861a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
86230833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff  void setNextClassCategory(ObjCCategoryDecl *Cat) {
86330833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff    NextClassCategory = Cat;
86430833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff  }
865980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void insertNextClassCategory() {
8663d58138992b9bc7b34aaa680f3ddf3971292eb7dSteve Naroff    NextClassCategory = ClassInterface->getCategoryList();
8673d58138992b9bc7b34aaa680f3ddf3971292eb7dSteve Naroff    ClassInterface->setCategoryList(this);
868980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
8691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Location information, modeled after the Stmt API.
870423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getLocStart() const { return getLocation(); } // '@'interface
871423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  SourceLocation getLocEnd() const { return EndLoc; }
872423cb565abc681b770fb4b9b4bc24d398c98157bSteve Naroff  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
8731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
874a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; }
875a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCCategoryDecl *D) { return true; }
876980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
8770c6b6243d3efd958c17943130e2a773653511edcSteve Naroff
878aecae629269fae3bf484baf1d109e9a89d14eeadArgyrios Kyrtzidisclass ObjCImplDecl : public ObjCContainerDecl {
8790d69b8cc8e90a9364771837cb42d7031b4cbb984Steve Naroff  /// Class interface for this class/category implementation
880a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *ClassInterface;
8811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8823aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattnerprotected:
8833aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  ObjCImplDecl(Kind DK, DeclContext *DC, SourceLocation L,
8843aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner               ObjCInterfaceDecl *classInterface)
8851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : ObjCContainerDecl(DK, DC, L,
8861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                        classInterface? classInterface->getIdentifier() : 0),
887aecae629269fae3bf484baf1d109e9a89d14eeadArgyrios Kyrtzidis      ClassInterface(classInterface) {}
8881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
88975c9cae5f85c72cbb1649e93849e16ede3f07522Chris Lattnerpublic:
890cddc88800bbd1213ec70ae5153c6a7f2e380fd8dChris Lattner  virtual ~ObjCImplDecl() {}
8911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
892e0def7589a8afa8a6acef13476bb3f882c104b91Chris Lattner  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
893e0def7589a8afa8a6acef13476bb3f882c104b91Chris Lattner  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
8948a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  void setClassInterface(ObjCInterfaceDecl *IFace);
8952c2d43c557beca1b4ba4bd743f33978aecb46a97Douglas Gregor
8961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  void addInstanceMethod(ObjCMethodDecl *method) {
8972c2d43c557beca1b4ba4bd743f33978aecb46a97Douglas Gregor    // FIXME: Context should be set correctly before we get here.
898653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor    method->setLexicalDeclContext(this);
8991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    addDecl(method);
900e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  }
9011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  void addClassMethod(ObjCMethodDecl *method) {
9022c2d43c557beca1b4ba4bd743f33978aecb46a97Douglas Gregor    // FIXME: Context should be set correctly before we get here.
903653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor    method->setLexicalDeclContext(this);
9041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    addDecl(method);
90553df12d1ba68dbd071d067f8236c16fba815aad5Chris Lattner  }
9061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
90717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  void addPropertyImplementation(ObjCPropertyImplDecl *property);
9081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
90917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
91017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
911653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor
912653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor  // Iterator access to properties.
913653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor  typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
9141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  propimpl_iterator propimpl_begin() const {
91517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return propimpl_iterator(decls_begin());
916559c0c4bbecc017aab0716d546c4fefbcc194687Fariborz Jahanian  }
9171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  propimpl_iterator propimpl_end() const {
91817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return propimpl_iterator(decls_end());
919559c0c4bbecc017aab0716d546c4fefbcc194687Fariborz Jahanian  }
920653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor
921bfb498d0996ef049efe9476f2802976fd145cd60Argyrios Kyrtzidis  static bool classof(const Decl *D) {
922bfb498d0996ef049efe9476f2802976fd145cd60Argyrios Kyrtzidis    return D->getKind() >= ObjCImplFirst && D->getKind() <= ObjCImplLast;
923bfb498d0996ef049efe9476f2802976fd145cd60Argyrios Kyrtzidis  }
924bfb498d0996ef049efe9476f2802976fd145cd60Argyrios Kyrtzidis  static bool classof(const ObjCImplDecl *D) { return true; }
9253aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner};
9261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ObjCCategoryImplDecl - An object of this class encapsulates a category
9281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// @implementation declaration. If a category class has declaration of a
9291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// property, its implementation must be specified in the category's
9303aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner/// @implementation declaration. Example:
9313aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner/// @interface I @end
9323aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner/// @interface I(CATEGORY)
9333aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner///    @property int p1, d1;
9343aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner/// @end
9353aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner/// @implementation I(CATEGORY)
9363aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner///  @dynamic p1,d1;
9373aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner/// @end
9383aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner///
9393aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner/// ObjCCategoryImplDecl
9403aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattnerclass ObjCCategoryImplDecl : public ObjCImplDecl {
9413aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  // Category name
9423aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  IdentifierInfo *Id;
9433aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner
9443aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  ObjCCategoryImplDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
9453aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner                       ObjCInterfaceDecl *classInterface)
9463aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner    : ObjCImplDecl(ObjCCategoryImpl, DC, L, classInterface), Id(Id) {}
9473aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattnerpublic:
9483aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
9493aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner                                      SourceLocation L, IdentifierInfo *Id,
9503aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner                                      ObjCInterfaceDecl *classInterface);
9511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9520d69b8cc8e90a9364771837cb42d7031b4cbb984Steve Naroff  /// getIdentifier - Get the identifier that names the category
9533aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  /// interface associated with this implementation.
9540d69b8cc8e90a9364771837cb42d7031b4cbb984Steve Naroff  /// FIXME: This is a bad API, we are overriding the NamedDecl::getIdentifier()
9550d69b8cc8e90a9364771837cb42d7031b4cbb984Steve Naroff  /// to mean something different. For example:
9560d69b8cc8e90a9364771837cb42d7031b4cbb984Steve Naroff  /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
9570d69b8cc8e90a9364771837cb42d7031b4cbb984Steve Naroff  /// returns the class interface name, whereas
9580d69b8cc8e90a9364771837cb42d7031b4cbb984Steve Naroff  /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
9590d69b8cc8e90a9364771837cb42d7031b4cbb984Steve Naroff  /// returns the category name.
9601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  IdentifierInfo *getIdentifier() const {
9611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return Id;
9623aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  }
96310b0e1fa3aabd8877dbbc0df1f2414e04afd5fddDouglas Gregor  void setIdentifier(IdentifierInfo *II) { Id = II; }
9641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9650d69b8cc8e90a9364771837cb42d7031b4cbb984Steve Naroff  ObjCCategoryDecl *getCategoryDecl() const;
96610b0e1fa3aabd8877dbbc0df1f2414e04afd5fddDouglas Gregor
967b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar  /// getName - Get the name of identifier for the class interface associated
968b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar  /// with this implementation as a StringRef.
969b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar  //
970b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar  // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
971b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar  // something different.
972b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar  llvm::StringRef getName() const {
973b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar    return Id ? Id->getNameStart() : "";
974b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar  }
975b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar
9763aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  /// getNameAsCString - Get the name of identifier for the class
9773aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  /// interface associated with this implementation as a C string
9783aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  /// (const char*).
9797fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  //
980b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar  // FIXME: Deprecated, move clients to getName().
9813aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  const char *getNameAsCString() const {
9827fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar    return Id ? Id->getNameStart() : "";
9833aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  }
9841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9853aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  /// @brief Get the name of the class associated with this interface.
9867fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  //
987b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar  // FIXME: Deprecated, move clients to getName().
9883aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  std::string getNameAsString() const {
989b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar    return getName();
9903aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  }
9911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
992a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;}
993a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCCategoryImplDecl *D) { return true; }
9948f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian};
9958f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
996a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCImplementationDecl - Represents a class definition - this is where
9970c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// method definitions are specified. For example:
9980c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
99998abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// @code
10000c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @implementation MyClass
10010c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - (void)myMethod { /* do something */ }
10020c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// @end
100398abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// @endcode
10040c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
10051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// Typically, instance variables are specified in the class interface,
1006ec0d7a6f4b0699cc9960e6d9fee0f957c64d1cf9Douglas Gregor/// *not* in the implementation. Nevertheless (for legacy reasons), we
100753df12d1ba68dbd071d067f8236c16fba815aad5Chris Lattner/// allow instance variables to be specified in the implementation.  When
100853df12d1ba68dbd071d067f8236c16fba815aad5Chris Lattner/// specified, they need to be *identical* to the interface.
10090c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
10101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ObjCImplementationDecl : public ObjCImplDecl {
1011980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Implementation Class's super class.
1012a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *SuperClass;
10131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ObjCImplementationDecl(DeclContext *DC, SourceLocation L,
1015a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                         ObjCInterfaceDecl *classInterface,
1016a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                         ObjCInterfaceDecl *superDecl)
10171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : ObjCImplDecl(ObjCImplementation, DC, L, classInterface),
10183aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner       SuperClass(superDecl){}
10191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic:
10201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
10211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                        SourceLocation L,
102275c9cae5f85c72cbb1649e93849e16ede3f07522Chris Lattner                                        ObjCInterfaceDecl *classInterface,
102375c9cae5f85c72cbb1649e93849e16ede3f07522Chris Lattner                                        ObjCInterfaceDecl *superDecl);
10241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10254afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  /// getIdentifier - Get the identifier that names the class
10264afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  /// interface associated with this implementation.
10271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  IdentifierInfo *getIdentifier() const {
10281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return getClassInterface()->getIdentifier();
10294afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  }
10304afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor
1031d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar  /// getName - Get the name of identifier for the class interface associated
1032d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar  /// with this implementation as a StringRef.
1033d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar  //
1034d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar  // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
1035d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar  // something different.
1036d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar  llvm::StringRef getName() const {
1037d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar    assert(getIdentifier() && "Name is not a simple identifier");
1038d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar    return getIdentifier()->getName();
1039d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar  }
1040d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar
10414afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  /// getNameAsCString - Get the name of identifier for the class
10424afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  /// interface associated with this implementation as a C string
10434afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  /// (const char*).
10447fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  //
10457fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  // FIXME: Move to StringRef API.
10464afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  const char *getNameAsCString() const {
1047d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar    return getName().data();
10484afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  }
10494afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor
10504afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  /// @brief Get the name of the class associated with this interface.
10517fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  //
10527fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  // FIXME: Move to StringRef API.
10534afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  std::string getNameAsString() const {
1054d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar    return getName();
10554afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  }
10564afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor
1057e0def7589a8afa8a6acef13476bb3f882c104b91Chris Lattner  const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
1058e0def7589a8afa8a6acef13476bb3f882c104b91Chris Lattner  ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
10591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1060f3a7af901231535191d14cb524d58f22907ac4d2Chris Lattner  void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
10611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10628f36aba016c2d236a90f9ecf0a66904209202202Douglas Gregor  typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
10631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ivar_iterator ivar_begin() const {
10641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return ivar_iterator(decls_begin());
10658f36aba016c2d236a90f9ecf0a66904209202202Douglas Gregor  }
10661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ivar_iterator ivar_end() const {
106717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return ivar_iterator(decls_end());
10688f36aba016c2d236a90f9ecf0a66904209202202Douglas Gregor  }
10691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  unsigned ivar_size() const {
107017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return std::distance(ivar_begin(), ivar_end());
10718f36aba016c2d236a90f9ecf0a66904209202202Douglas Gregor  }
10721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool ivar_empty() const {
107317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return ivar_begin() == ivar_end();
10748f36aba016c2d236a90f9ecf0a66904209202202Douglas Gregor  }
10751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1076980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  static bool classof(const Decl *D) {
1077a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    return D->getKind() == ObjCImplementation;
1078980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
1079a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCImplementationDecl *D) { return true; }
1080980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
1081243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian
10821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
1083243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian/// declared as @compatibility_alias alias class.
10844afa39deaa245592977136d367251ee2c173dd8dDouglas Gregorclass ObjCCompatibleAliasDecl : public NamedDecl {
1085243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  /// Class that this is an alias of.
1086a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *AliasedClass;
10871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1088d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
1089e8043c39176e7f253fbd92982b077eca6bf2fd59Steve Naroff                          ObjCInterfaceDecl* aliasedClass)
10904afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {}
1091f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattnerpublic:
1092d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC,
10930ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner                                         SourceLocation L, IdentifierInfo *Id,
1094f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner                                         ObjCInterfaceDecl* aliasedClass);
1095f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner
1096f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner  const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
1097f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner  ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
109830833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff  void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
10991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1100243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  static bool classof(const Decl *D) {
11018a934233d1582b5bde9d270bc0705aa81e471a79Chris Lattner    return D->getKind() == ObjCCompatibleAlias;
1102243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  }
1103a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCCompatibleAliasDecl *D) { return true; }
11041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1105243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian};
11061de1e74541c25c1a7b721f1c3991ea34c8403420Fariborz Jahanian
11071de1e74541c25c1a7b721f1c3991ea34c8403420Fariborz Jahanian/// ObjCPropertyDecl - Represents one property declaration in an interface.
11081de1e74541c25c1a7b721f1c3991ea34c8403420Fariborz Jahanian/// For example:
11091de1e74541c25c1a7b721f1c3991ea34c8403420Fariborz Jahanian/// @property (assign, readwrite) int MyProperty;
11101de1e74541c25c1a7b721f1c3991ea34c8403420Fariborz Jahanian///
11114afa39deaa245592977136d367251ee2c173dd8dDouglas Gregorclass ObjCPropertyDecl : public NamedDecl {
111282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanianpublic:
1113a5674258f5e6f74f1c0ed3ece4d64fbb1b9afb11Chris Lattner  enum PropertyAttributeKind {
11141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    OBJC_PR_noattr    = 0x00,
11151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    OBJC_PR_readonly  = 0x01,
1116a5674258f5e6f74f1c0ed3ece4d64fbb1b9afb11Chris Lattner    OBJC_PR_getter    = 0x02,
11171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    OBJC_PR_assign    = 0x04,
11181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    OBJC_PR_readwrite = 0x08,
1119a5674258f5e6f74f1c0ed3ece4d64fbb1b9afb11Chris Lattner    OBJC_PR_retain    = 0x10,
11201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    OBJC_PR_copy      = 0x20,
1121a5674258f5e6f74f1c0ed3ece4d64fbb1b9afb11Chris Lattner    OBJC_PR_nonatomic = 0x40,
1122a5674258f5e6f74f1c0ed3ece4d64fbb1b9afb11Chris Lattner    OBJC_PR_setter    = 0x80
1123a5674258f5e6f74f1c0ed3ece4d64fbb1b9afb11Chris Lattner  };
1124af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
1125af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  enum SetterKind { Assign, Retain, Copy };
112646b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian  enum PropertyControl { None, Required, Optional };
112782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanianprivate:
1128dae1a1a2aa4f245b1958dc8db6089f24c575ef13Fariborz Jahanian  QualType DeclType;
1129ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  unsigned PropertyAttributes : 8;
11301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
113146b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian  // @required/@optional
113246b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian  unsigned PropertyImplementation : 2;
11331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11345251e130a23d997f7c0dfdc250cdc41f179e5bedFariborz Jahanian  Selector GetterName;    // getter name of NULL if no getter
11355251e130a23d997f7c0dfdc250cdc41f179e5bedFariborz Jahanian  Selector SetterName;    // setter name of NULL if no setter
11361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
113733de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian  ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
113833de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian  ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
1139af3e72285238369c2ea4ebd40a1c9a87bd3eabb7Fariborz Jahanian  ObjCIvarDecl *PropertyIvarDecl;   // Synthesize ivar for this property
114033de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian
11411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
1142d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor                   QualType T)
11434afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    : NamedDecl(ObjCProperty, DC, L, Id), DeclType(T),
114433de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian      PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None),
11451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      GetterName(Selector()),
114633de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian      SetterName(Selector()),
1147af3e72285238369c2ea4ebd40a1c9a87bd3eabb7Fariborz Jahanian      GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {}
1148f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattnerpublic:
11491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
11501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                  SourceLocation L,
115146b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian                                  IdentifierInfo *Id, QualType T,
115246b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian                                  PropertyControl propControl = None);
1153dae1a1a2aa4f245b1958dc8db6089f24c575ef13Fariborz Jahanian  QualType getType() const { return DeclType; }
115470e5a14c6076d63833c62d1d6d628c26309897c1Douglas Gregor  void setType(QualType T) { DeclType = T; }
115570e5a14c6076d63833c62d1d6d628c26309897c1Douglas Gregor
1156a5674258f5e6f74f1c0ed3ece4d64fbb1b9afb11Chris Lattner  PropertyAttributeKind getPropertyAttributes() const {
1157f4af5154571e0c5eadb19df10e65464766ef6683Chris Lattner    return PropertyAttributeKind(PropertyAttributes);
1158f4af5154571e0c5eadb19df10e65464766ef6683Chris Lattner  }
11591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  void setPropertyAttributes(PropertyAttributeKind PRVal) {
1160a5674258f5e6f74f1c0ed3ece4d64fbb1b9afb11Chris Lattner    PropertyAttributes |= PRVal;
116182a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  }
1162394d33f1f602f7681032a659dff5bb09061ee510Daniel Dunbar
11638cf0bb3c2a798ce3acacaac2d3178648cd4c65c6Fariborz Jahanian void makeitReadWriteAttribute(void) {
11648cf0bb3c2a798ce3acacaac2d3178648cd4c65c6Fariborz Jahanian    PropertyAttributes &= ~OBJC_PR_readonly;
11658cf0bb3c2a798ce3acacaac2d3178648cd4c65c6Fariborz Jahanian    PropertyAttributes |= OBJC_PR_readwrite;
11661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump }
11678cf0bb3c2a798ce3acacaac2d3178648cd4c65c6Fariborz Jahanian
1168af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  // Helper methods for accessing attributes.
1169af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
1170af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  /// isReadOnly - Return true iff the property has a setter.
1171394d33f1f602f7681032a659dff5bb09061ee510Daniel Dunbar  bool isReadOnly() const {
1172394d33f1f602f7681032a659dff5bb09061ee510Daniel Dunbar    return (PropertyAttributes & OBJC_PR_readonly);
1173394d33f1f602f7681032a659dff5bb09061ee510Daniel Dunbar  }
1174af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
1175af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  /// getSetterKind - Return the method used for doing assignment in
1176af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  /// the property setter. This is only valid if the property has been
1177af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  /// defined to have a setter.
1178af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  SetterKind getSetterKind() const {
1179af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar    if (PropertyAttributes & OBJC_PR_retain)
1180af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar      return Retain;
1181af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar    if (PropertyAttributes & OBJC_PR_copy)
1182af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar      return Copy;
1183af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar    return Assign;
1184af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  }
1185af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
11865251e130a23d997f7c0dfdc250cdc41f179e5bedFariborz Jahanian  Selector getGetterName() const { return GetterName; }
11875251e130a23d997f7c0dfdc250cdc41f179e5bedFariborz Jahanian  void setGetterName(Selector Sel) { GetterName = Sel; }
11881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11895251e130a23d997f7c0dfdc250cdc41f179e5bedFariborz Jahanian  Selector getSetterName() const { return SetterName; }
11905251e130a23d997f7c0dfdc250cdc41f179e5bedFariborz Jahanian  void setSetterName(Selector Sel) { SetterName = Sel; }
11911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
119233de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian  ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
119333de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian  void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
119433de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian
119533de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian  ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
119633de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian  void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
11971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
119846b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian  // Related to @optional/@required declared in @protocol
119946b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian  void setPropertyImplementation(PropertyControl pc) {
120046b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian    PropertyImplementation = pc;
120146b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian  }
120246b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian  PropertyControl getPropertyImplementation() const {
120346b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian    return PropertyControl(PropertyImplementation);
12041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
12051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1206af3e72285238369c2ea4ebd40a1c9a87bd3eabb7Fariborz Jahanian  void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
1207af3e72285238369c2ea4ebd40a1c9a87bd3eabb7Fariborz Jahanian    PropertyIvarDecl = Ivar;
1208af3e72285238369c2ea4ebd40a1c9a87bd3eabb7Fariborz Jahanian  }
1209af3e72285238369c2ea4ebd40a1c9a87bd3eabb7Fariborz Jahanian  ObjCIvarDecl *getPropertyIvarDecl() const {
1210af3e72285238369c2ea4ebd40a1c9a87bd3eabb7Fariborz Jahanian    return PropertyIvarDecl;
1211af3e72285238369c2ea4ebd40a1c9a87bd3eabb7Fariborz Jahanian  }
12121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
121382a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  static bool classof(const Decl *D) {
1214670aa9d7639278f507930e95dc89c12032ab7c7eSam Bishop    return D->getKind() == ObjCProperty;
121582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  }
1216a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  static bool classof(const ObjCPropertyDecl *D) { return true; }
121782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian};
1218980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
12191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ObjCPropertyImplDecl - Represents implementation declaration of a property
122061d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian/// in a class or category implementation block. For example:
122161d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian/// @synthesize prop1 = ivar1;
122261d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian///
12234afa39deaa245592977136d367251ee2c173dd8dDouglas Gregorclass ObjCPropertyImplDecl : public Decl {
122461d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanianpublic:
12259f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbar  enum Kind {
12269f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbar    Synthesize,
12279f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbar    Dynamic
122861d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian  };
122961d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanianprivate:
1230559c0c4bbecc017aab0716d546c4fefbcc194687Fariborz Jahanian  SourceLocation AtLoc;   // location of @synthesize or @dynamic
123161d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian  /// Property declaration being implemented
123261d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian  ObjCPropertyDecl *PropertyDecl;
1233be57c3a3fef0776fca57ad88b2db263f37b074c4Ted Kremenek
123461d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian  /// Null for @dynamic. Required for @synthesize.
123561d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian  ObjCIvarDecl *PropertyIvarDecl;
1236be57c3a3fef0776fca57ad88b2db263f37b074c4Ted Kremenek
1237d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
12381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       ObjCPropertyDecl *property,
12391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       Kind PK,
1240628b96f34e93b643b6e15e75eabb8d96079a7e27Fariborz Jahanian                       ObjCIvarDecl *ivarDecl)
12411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
1242d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor      PropertyDecl(property), PropertyIvarDecl(ivarDecl) {
12439f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbar    assert (PK == Dynamic || PropertyIvarDecl);
12449f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbar  }
12451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12469f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbarpublic:
1247d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC,
12481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                      SourceLocation atLoc, SourceLocation L,
12491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                      ObjCPropertyDecl *property,
12501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                      Kind PK,
1251628b96f34e93b643b6e15e75eabb8d96079a7e27Fariborz Jahanian                                      ObjCIvarDecl *ivarDecl);
125261d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian
12531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  virtual SourceRange getSourceRange() const {
12541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return SourceRange(AtLoc, getLocation());
1255ddfd4c9eda34765b08fae4cb31ad5a365face107Argyrios Kyrtzidis  }
1256d40910b581b09c937a8c1fdcde9b8ec724398fb9Steve Naroff  SourceLocation getLocStart() const { return AtLoc; }
12578818c4fb69cb2a4eec94b217a90f94f9e075296eDouglas Gregor  void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
1258d40910b581b09c937a8c1fdcde9b8ec724398fb9Steve Naroff
1259be57c3a3fef0776fca57ad88b2db263f37b074c4Ted Kremenek  ObjCPropertyDecl *getPropertyDecl() const {
1260be57c3a3fef0776fca57ad88b2db263f37b074c4Ted Kremenek    return PropertyDecl;
1261be57c3a3fef0776fca57ad88b2db263f37b074c4Ted Kremenek  }
12628818c4fb69cb2a4eec94b217a90f94f9e075296eDouglas Gregor  void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; }
12638818c4fb69cb2a4eec94b217a90f94f9e075296eDouglas Gregor
12649f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbar  Kind getPropertyImplementation() const {
12659f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbar    return PropertyIvarDecl ? Synthesize : Dynamic;
1266be57c3a3fef0776fca57ad88b2db263f37b074c4Ted Kremenek  }
12671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1268af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCIvarDecl *getPropertyIvarDecl() const {
1269be57c3a3fef0776fca57ad88b2db263f37b074c4Ted Kremenek    return PropertyIvarDecl;
1270be57c3a3fef0776fca57ad88b2db263f37b074c4Ted Kremenek  }
12718818c4fb69cb2a4eec94b217a90f94f9e075296eDouglas Gregor  void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; }
12728818c4fb69cb2a4eec94b217a90f94f9e075296eDouglas Gregor
127361d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian  static bool classof(const Decl *D) {
127461d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian    return D->getKind() == ObjCPropertyImpl;
127561d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian  }
12761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const ObjCPropertyImplDecl *D) { return true; }
127761d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian};
127861d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian
1279980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff}  // end namespace clang
1280980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff#endif
1281