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"
18491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis#include "clang/AST/SelectorLocationsKind.h"
196ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson#include "llvm/ADT/STLExtras.h"
20aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar#include "llvm/Support/Compiler.h"
21980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
22980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffnamespace clang {
23980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass Expr;
24980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass Stmt;
25980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffclass FunctionDecl;
2660f8c868ffb346b78451a3eccaecd0461d2ae498Fariborz Jahanianclass RecordDecl;
27a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCIvarDecl;
28a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCMethodDecl;
29a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCProtocolDecl;
30a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCCategoryDecl;
31a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCPropertyDecl;
32f624f8186d8fe474350051c6d3f00b2c204fbeaeFariborz Jahanianclass ObjCPropertyImplDecl;
33cbb67480094b3bcb5b715acd827cbad55e2a204cSean Huntclass CXXCtorInitializer;
3468835718c4125f2f66740cd04de7088645ec695dChris Lattner
35793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattnerclass ObjCListBase {
360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  ObjCListBase(const ObjCListBase &) = delete;
370e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void operator=(const ObjCListBase &) = delete;
38793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattnerprotected:
39793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  /// List is an array of pointers to objects that are not owned by this object.
40793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  void **List;
413db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  unsigned NumElts;
42793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner
433db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattnerpublic:
446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCListBase() : List(nullptr), NumElts(0) {}
45793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  unsigned size() const { return NumElts; }
46793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  bool empty() const { return NumElts == 0; }
471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
48793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattnerprotected:
4938af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  void set(void *const* InList, unsigned Elts, ASTContext &Ctx);
50793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner};
511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
53793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner/// ObjCList - This is a simple template class used to hold various lists of
54793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner/// decls etc, which is heavily used by the ObjC front-end.  This only use case
55793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner/// this supports is setting the list all at once and then reading elements out
56793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner/// of it.
57793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattnertemplate <typename T>
58793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattnerclass ObjCList : public ObjCListBase {
59793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattnerpublic:
6038af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  void set(T* const* InList, unsigned Elts, ASTContext &Ctx) {
6138af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner    ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx);
62793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  }
631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
64793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  typedef T* const * iterator;
65793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  iterator begin() const { return (iterator)List; }
66793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  iterator end() const { return (iterator)List+NumElts; }
671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
68793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner  T* operator[](unsigned Idx) const {
69793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner    assert(Idx < NumElts && "Invalid access");
70793ccfd646d0388e06c587e962a18fa723b72f02Chris Lattner    return (T*)List[Idx];
713db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  }
723db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner};
733db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner
7418df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor/// \brief A list of Objective-C protocols, along with the source
7518df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor/// locations at which they were referenced.
7618df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregorclass ObjCProtocolList : public ObjCList<ObjCProtocolDecl> {
7718df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  SourceLocation *Locations;
7818df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor
7918df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  using ObjCList<ObjCProtocolDecl>::set;
8018df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor
8118df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregorpublic:
826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(nullptr) { }
8318df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor
8418df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  typedef const SourceLocation *loc_iterator;
8518df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  loc_iterator loc_begin() const { return Locations; }
8618df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  loc_iterator loc_end() const { return Locations + size(); }
8718df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor
88ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  void set(ObjCProtocolDecl* const* InList, unsigned Elts,
8918df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor           const SourceLocation *Locs, ASTContext &Ctx);
9018df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor};
911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
93a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCMethodDecl - Represents an instance or class method declaration.
9458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// ObjC methods can be declared within 4 contexts: class interfaces,
9558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// categories, protocols, and class implementations. While C++ member
961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// functions leverage C syntax, Objective-C method syntax is modeled after
971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// Smalltalk (using colons to specify argument types/expressions).
9858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// Here are some brief examples:
9958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff///
10058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// Setter/getter instance methods:
10158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// - (void)setMenu:(NSMenu *)menu;
1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// - (NSMenu *)menu;
1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
10458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// Instance method that takes 2 NSView arguments:
10558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
10658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff///
10758dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// Getter class method:
10858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// + (NSMenu *)defaultMenu;
10958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff///
11058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// A selector represents a unique name for a method. The selector names for
11158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
11258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff///
1134afa39deaa245592977136d367251ee2c173dd8dDouglas Gregorclass ObjCMethodDecl : public NamedDecl, public DeclContext {
11458dbdeb69c063f82d644504fc638120198f7fad2Steve Naroffpublic:
11558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  enum ImplementationControl { None, Required, Optional };
11658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroffprivate:
11785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // The conventional meaning of this method; an ObjCMethodFamily.
11885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // This is not serialized; instead, it is computed on demand and
11985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // cached.
12085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  mutable unsigned Family : ObjCMethodFamilyBitWidth;
12185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
12258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// instance (true) or class (false) method.
12385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  unsigned IsInstance : 1;
12485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  unsigned IsVariadic : 1;
1251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1261e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose  /// True if this method is the getter or setter for an explicit property.
1271e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose  unsigned IsPropertyAccessor : 1;
128ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1293fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian  // Method has a definition.
13085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  unsigned IsDefined : 1;
1311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13272b2625aa67c8213acaf4bf6209b67859d60e2cfArgyrios Kyrtzidis  /// \brief Method redeclaration in the same interface.
1333a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis  unsigned IsRedeclaration : 1;
1343a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis
13572b2625aa67c8213acaf4bf6209b67859d60e2cfArgyrios Kyrtzidis  /// \brief Is redeclared in the same interface.
13672b2625aa67c8213acaf4bf6209b67859d60e2cfArgyrios Kyrtzidis  mutable unsigned HasRedeclaration : 1;
13772b2625aa67c8213acaf4bf6209b67859d60e2cfArgyrios Kyrtzidis
138ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
13941c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// \@required/\@optional
140ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  unsigned DeclImplementation : 2;
1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
142ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
14358dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// in, inout, etc.
144ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  unsigned objcDeclQualifier : 6;
1451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
146926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  /// \brief Indicates whether this method has a related result type.
147926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  unsigned RelatedResultType : 1;
148ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
149491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  /// \brief Whether the locations of the selector identifiers are in a
150491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  /// "standard" position, a enum SelectorLocationsKind.
151491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  unsigned SelLocsKind : 2;
1527732cc9c0fdc97a2f8cce4e5933d8103213d1aefFariborz Jahanian
153e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  /// \brief Whether this method overrides any other in the class hierarchy.
154e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  ///
155e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  /// A method is said to override any method in the class's
156e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  /// base classes, its protocols, or its categories' protocols, that has
157e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  /// the same selector and is of the same kind (class or instance).
158e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  /// A method in an implementation is not considered as overriding the same
159e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  /// method in the interface or its categories.
160e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  unsigned IsOverriding : 1;
161e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis
16235f3f36cb9451f347b83a6e7f01e3c702df4732dArgyrios Kyrtzidis  /// \brief Indicates if the method was a definition but its body was skipped.
16335f3f36cb9451f347b83a6e7f01e3c702df4732dArgyrios Kyrtzidis  unsigned HasSkippedBody : 1;
16435f3f36cb9451f347b83a6e7f01e3c702df4732dArgyrios Kyrtzidis
165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Return type of this method.
16658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  QualType MethodDeclType;
167ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Type source information for the return type.
169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  TypeSourceInfo *ReturnTInfo;
1704bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor
171491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  /// \brief Array of ParmVarDecls for the formal parameters of this method
172491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  /// and optionally followed by selector locations.
173491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  void *ParamsAndSelLocs;
174491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  unsigned NumParams;
1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  /// List of attributes for this method declaration.
177a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios Kyrtzidis  SourceLocation DeclEndLoc; // the location of the ';' or '{'.
1781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17958dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // The following are only used for method definitions, null otherwise.
1805456b0fe40714a78cd0ba7c1a5b7dc34eda385afDouglas Gregor  LazyDeclStmtPtr Body;
181451318c08a6342c10b8986060386fd9274418437Daniel Dunbar
182451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  /// SelfDecl - Decl for the implicit self parameter. This is lazily
183451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  /// constructed by createImplicitParams.
1844111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  ImplicitParamDecl *SelfDecl;
185451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily
186451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  /// constructed by createImplicitParams.
1874111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  ImplicitParamDecl *CmdDecl;
1881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
189491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  SelectorLocationsKind getSelLocsKind() const {
190491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    return (SelectorLocationsKind)SelLocsKind;
191491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  }
192491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  bool hasStandardSelLocs() const {
193491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    return getSelLocsKind() != SelLoc_NonStandard;
194491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  }
195491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
196491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  /// \brief Get a pointer to the stored selector identifiers locations array.
197491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  /// No locations will be stored if HasStandardSelLocs is true.
198491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  SourceLocation *getStoredSelLocs() {
199491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    return reinterpret_cast<SourceLocation*>(getParams() + NumParams);
200491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  }
201491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  const SourceLocation *getStoredSelLocs() const {
202491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    return reinterpret_cast<const SourceLocation*>(getParams() + NumParams);
203491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  }
204491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
205491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  /// \brief Get a pointer to the stored selector identifiers locations array.
206491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  /// No locations will be stored if HasStandardSelLocs is true.
207491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  ParmVarDecl **getParams() {
208491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    return reinterpret_cast<ParmVarDecl **>(ParamsAndSelLocs);
209491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  }
210491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  const ParmVarDecl *const *getParams() const {
211491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    return reinterpret_cast<const ParmVarDecl *const *>(ParamsAndSelLocs);
212491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  }
213491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
214491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  /// \brief Get the number of stored selector identifiers locations.
215491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  /// No locations will be stored if HasStandardSelLocs is true.
216491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  unsigned getNumStoredSelLocs() const {
217491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    if (hasStandardSelLocs())
218491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis      return 0;
219491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    return getNumSelectorLocs();
220491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  }
221491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
222491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  void setParamsAndSelLocs(ASTContext &C,
223491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                           ArrayRef<ParmVarDecl*> Params,
224491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                           ArrayRef<SourceLocation> SelLocs);
225491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
226a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
227651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                 Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
228651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                 DeclContext *contextDecl, bool isInstance = true,
229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                 bool isVariadic = false, bool isPropertyAccessor = false,
230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                 bool isImplicitlyDeclared = false, bool isDefined = false,
2317732cc9c0fdc97a2f8cce4e5933d8103213d1aefFariborz Jahanian                 ImplementationControl impControl = None,
232da92a7f91cf88f49e02050919676f7fb8e3bdff8Argyrios Kyrtzidis                 bool HasRelatedResultType = false)
233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        IsInstance(isInstance), IsVariadic(isVariadic),
236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        IsPropertyAccessor(isPropertyAccessor), IsDefined(isDefined),
237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl),
238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        objcDeclQualifier(OBJC_TQ_None),
239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        RelatedResultType(HasRelatedResultType),
240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0),
2416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        MethodDeclType(T), ReturnTInfo(ReturnTInfo), ParamsAndSelLocs(nullptr),
2426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        NumParams(0), DeclEndLoc(endLoc), Body(), SelfDecl(nullptr),
2436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        CmdDecl(nullptr) {
24475cf3e86d33ce810c12084126385371b335c30baArgyrios Kyrtzidis    setImplicit(isImplicitlyDeclared);
24575cf3e86d33ce810c12084126385371b335c30baArgyrios Kyrtzidis  }
2468a779314870760848e61da2c428a78971fe3f1c3Ted Kremenek
24757ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis  /// \brief A definition will return its interface declaration.
24857ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis  /// An interface declaration will return its definition.
24957ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis  /// Otherwise it will return itself.
2506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCMethodDecl *getNextRedeclarationImpl() override;
251da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor
2526c4ae5de0c356777446f823b573821fb95560d91Chris Lattnerpublic:
253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  static ObjCMethodDecl *
254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         DeclContext *contextDecl, bool isInstance = true,
257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         bool isVariadic = false, bool isPropertyAccessor = false,
258651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         bool isImplicitlyDeclared = false, bool isDefined = false,
259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         ImplementationControl impControl = None,
260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         bool HasRelatedResultType = false);
261e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis
2621e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ObjCMethodDecl *getCanonicalDecl() override;
26513e635c55eb23f736d38abf9c954801bd6482db4Ted Kremenek  const ObjCMethodDecl *getCanonicalDecl() const {
26613e635c55eb23f736d38abf9c954801bd6482db4Ted Kremenek    return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
26713e635c55eb23f736d38abf9c954801bd6482db4Ted Kremenek  }
268e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis
269ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  ObjCDeclQualifier getObjCDeclQualifier() const {
270ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek    return ObjCDeclQualifier(objcDeclQualifier);
271ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  }
272a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
2731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
274926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  /// \brief Determine whether this method has a result type that is related
275926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  /// to the message receiver's type.
276926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  bool hasRelatedResultType() const { return RelatedResultType; }
277ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
278926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  /// \brief Note whether this method has a related result type.
279926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; }
2803a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis
2813a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis  /// \brief True if this is a method redeclaration in the same interface.
2823a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis  bool isRedeclaration() const { return IsRedeclaration; }
2833a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis  void setAsRedeclaration(const ObjCMethodDecl *PrevMethod);
284ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
285a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios Kyrtzidis  /// \brief Returns the location where the declarator ends. It will be
286a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios Kyrtzidis  /// the location of ';' for a method declaration and the location of '{'
287a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios Kyrtzidis  /// for a method definition.
288a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios Kyrtzidis  SourceLocation getDeclaratorEndLoc() const { return DeclEndLoc; }
289a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios Kyrtzidis
29058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Location information, modeled after the Stmt API.
291aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); }
292a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios Kyrtzidis  SourceLocation getLocEnd() const LLVM_READONLY;
293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SourceRange getSourceRange() const override LLVM_READONLY {
294a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios Kyrtzidis    return SourceRange(getLocation(), getLocEnd());
2959776ba0d844cf9f6888e871e3fd246ae782f76f4Daniel Dunbar  }
2961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
297746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis  SourceLocation getSelectorStartLoc() const {
298746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis    if (isImplicit())
299746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis      return getLocStart();
300746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis    return getSelectorLoc(0);
301746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis  }
302491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  SourceLocation getSelectorLoc(unsigned Index) const {
303491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    assert(Index < getNumSelectorLocs() && "Index out of range!");
304491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    if (hasStandardSelLocs())
305491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis      return getStandardSelectorLoc(Index, getSelector(),
306491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                                   getSelLocsKind() == SelLoc_StandardWithSpace,
307651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    parameters(),
308a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios Kyrtzidis                                   DeclEndLoc);
309491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    return getStoredSelLocs()[Index];
310491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  }
311491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
312491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
313491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
314491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  unsigned getNumSelectorLocs() const {
315491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    if (isImplicit())
316491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis      return 0;
317491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    Selector Sel = getSelector();
318491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    if (Sel.isUnarySelector())
319491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis      return 1;
320491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    return Sel.getNumArgs();
321491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  }
322491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
3235619688510185081cbb4621d703daf7ee24cf39aChris Lattner  ObjCInterfaceDecl *getClassInterface();
3245619688510185081cbb4621d703daf7ee24cf39aChris Lattner  const ObjCInterfaceDecl *getClassInterface() const {
3255619688510185081cbb4621d703daf7ee24cf39aChris Lattner    return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
326e0def7589a8afa8a6acef13476bb3f882c104b91Chris Lattner  }
3271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3282e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor  Selector getSelector() const { return getDeclName().getObjCSelector(); }
3293a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson
330651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  QualType getReturnType() const { return MethodDeclType; }
331651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void setReturnType(QualType T) { MethodDeclType = T; }
332176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  SourceRange getReturnTypeSourceRange() const;
3331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
334ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Determine the type of an expression that sends a message to this
3355291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor  /// function.
3365291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor  QualType getSendResultType() const {
337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return getReturnType().getNonLValueExprType(getASTContext());
3385291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor  }
339ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
340651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  TypeSourceInfo *getReturnTypeSourceInfo() const { return ReturnTInfo; }
341651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void setReturnTypeSourceInfo(TypeSourceInfo *TInfo) { ReturnTInfo = TInfo; }
3424bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor
343d57f635d520e8cb5b93d3d770ff58db06c62de54Chris Lattner  // Iterator access to formal parameters.
344491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  unsigned param_size() const { return NumParams; }
345491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  typedef const ParmVarDecl *const *param_const_iterator;
346491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  typedef ParmVarDecl *const *param_iterator;
347651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<param_iterator> param_range;
348651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<param_const_iterator> param_const_range;
349651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  param_range params() { return param_range(param_begin(), param_end()); }
351651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  param_const_range params() const {
352651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return param_const_range(param_begin(), param_end());
353651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  param_const_iterator param_begin() const {
356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return param_const_iterator(getParams());
357651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
358651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  param_const_iterator param_end() const {
359651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return param_const_iterator(getParams() + NumParams);
360651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
361651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  param_iterator param_begin() { return param_iterator(getParams()); }
362651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  param_iterator param_end() { return param_iterator(getParams() + NumParams); }
363651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3647732cc9c0fdc97a2f8cce4e5933d8103213d1aefFariborz Jahanian  // This method returns and of the parameters which are part of the selector
3657732cc9c0fdc97a2f8cce4e5933d8103213d1aefFariborz Jahanian  // name mangling requirements.
366ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  param_const_iterator sel_param_end() const {
367ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    return param_begin() + getSelector().getNumArgs();
3687732cc9c0fdc97a2f8cce4e5933d8103213d1aefFariborz Jahanian  }
36989951a86b594513c2a013532ed45d197413b1087Chris Lattner
370651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // ArrayRef access to formal parameters.  This should eventually
371651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // replace the iterator interface above.
372651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ArrayRef<ParmVarDecl*> parameters() const {
373651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
374651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                              NumParams);
375651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
376651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3779dd0065e61ea4b48b19eee550704ce964e64e946Argyrios Kyrtzidis  /// \brief Sets the method's parameters and selector source locations.
3781824d54df85a462ada812dadda18130f951d40f3Dmitri Gribenko  /// If the method is implicit (not coming from source) \p SelLocs is
3799dd0065e61ea4b48b19eee550704ce964e64e946Argyrios Kyrtzidis  /// ignored.
380491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  void setMethodParams(ASTContext &C,
381491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                       ArrayRef<ParmVarDecl*> Params,
382176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                       ArrayRef<SourceLocation> SelLocs = llvm::None);
3834111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
3846ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson  // Iterator access to parameter types.
3856ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson  typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
386491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  typedef llvm::mapped_iterator<param_const_iterator, deref_fun>
387651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  param_type_iterator;
3886ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson
389651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  param_type_iterator param_type_begin() const {
3906ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson    return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
3916ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson  }
392651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  param_type_iterator param_type_end() const {
3936ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson    return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType));
3946ea8e2152e1ba93b4c80e7268403a582896dc3dcAnders Carlsson  }
3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
396451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  /// createImplicitParams - Used to lazily create the self and cmd
397451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  /// implict parameters. This must be called prior to using getSelfDecl()
398451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  /// or getCmdDecl(). The call is ignored if the implicit paramters
399451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  /// have already been created.
400fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanian  void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
401451318c08a6342c10b8986060386fd9274418437Daniel Dunbar
4024111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
40353c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff  void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; }
4044111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
40553c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff  void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; }
4061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  /// Determines the family of this method.
40885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  ObjCMethodFamily getMethodFamily() const;
40985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
410f8d49f64ef6ab7e632717a31631fc289aab69428Douglas Gregor  bool isInstanceMethod() const { return IsInstance; }
41153c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff  void setInstanceMethod(bool isInst) { IsInstance = isInst; }
41258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  bool isVariadic() const { return IsVariadic; }
41353c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff  void setVariadic(bool isVar) { IsVariadic = isVar; }
4141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
415f8d49f64ef6ab7e632717a31631fc289aab69428Douglas Gregor  bool isClassMethod() const { return !IsInstance; }
416f8d49f64ef6ab7e632717a31631fc289aab69428Douglas Gregor
4171e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose  bool isPropertyAccessor() const { return IsPropertyAccessor; }
4181e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose  void setPropertyAccessor(bool isAccessor) { IsPropertyAccessor = isAccessor; }
419ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4203fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian  bool isDefined() const { return IsDefined; }
4213fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian  void setDefined(bool isDefined) { IsDefined = isDefined; }
4221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
423e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  /// \brief Whether this method overrides any other in the class hierarchy.
424e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  ///
425e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  /// A method is said to override any method in the class's
426e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  /// base classes, its protocols, or its categories' protocols, that has
427e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  /// the same selector and is of the same kind (class or instance).
428e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  /// A method in an implementation is not considered as overriding the same
429e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  /// method in the interface or its categories.
430e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  bool isOverriding() const { return IsOverriding; }
431e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  void setOverriding(bool isOverriding) { IsOverriding = isOverriding; }
432740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
433740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  /// \brief Return overridden methods for the given \p Method.
434740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  ///
435740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  /// An ObjC method is considered to override any method in the class's
436bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian  /// base classes (and base's categories), its protocols, or its categories'
437bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian  /// protocols, that has
438740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  /// the same selector and is of the same kind (class or instance).
439740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  /// A method in an implementation is not considered as overriding the same
440740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  /// method in the interface or its categories.
441740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  void getOverriddenMethods(
442740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis                     SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const;
44304bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose
44435f3f36cb9451f347b83a6e7f01e3c702df4732dArgyrios Kyrtzidis  /// \brief True if the method was a definition but its body was skipped.
44535f3f36cb9451f347b83a6e7f01e3c702df4732dArgyrios Kyrtzidis  bool hasSkippedBody() const { return HasSkippedBody; }
44635f3f36cb9451f347b83a6e7f01e3c702df4732dArgyrios Kyrtzidis  void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
44735f3f36cb9451f347b83a6e7f01e3c702df4732dArgyrios Kyrtzidis
44804bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  /// \brief Returns the property associated with this method's selector.
44904bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  ///
45004bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  /// Note that even if this particular method is not marked as a property
45104bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  /// accessor, it is still possible for it to match a property declared in a
45204bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  /// superclass. Pass \c false if you only want to check the current class.
45304bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  const ObjCPropertyDecl *findPropertyDecl(bool CheckOverrides = true) const;
45404bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose
45541c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  // Related to protocols declared in  \@protocol
4561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  void setDeclImplementation(ImplementationControl ic) {
4571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    DeclImplementation = ic;
45858dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
4591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ImplementationControl getImplementationControl() const {
4601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return ImplementationControl(DeclImplementation);
46158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
462792481eec23d8c1aa92173be589e2ae9d02514a5Ted Kremenek
463651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Returns true if this specific method declaration is marked with the
464651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// designated initializer attribute.
465651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool isThisDeclarationADesignatedInitializer() const;
466651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
467651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Returns true if the method selector resolves to a designated initializer
468651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// in the class's interface.
469651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///
470651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \param InitMethod if non-null and the function returns true, it receives
471651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// the method declaration that was marked with the designated initializer
472651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// attribute.
473651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool isDesignatedInitializerForTheInterface(
4746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      const ObjCMethodDecl **InitMethod = nullptr) const;
475651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4765456b0fe40714a78cd0ba7c1a5b7dc34eda385afDouglas Gregor  /// \brief Determine whether this method has a body.
477651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool hasBody() const override { return Body.isValid(); }
4785456b0fe40714a78cd0ba7c1a5b7dc34eda385afDouglas Gregor
4795456b0fe40714a78cd0ba7c1a5b7dc34eda385afDouglas Gregor  /// \brief Retrieve the body of this method, if it has one.
480651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Stmt *getBody() const override;
4815456b0fe40714a78cd0ba7c1a5b7dc34eda385afDouglas Gregor
4825456b0fe40714a78cd0ba7c1a5b7dc34eda385afDouglas Gregor  void setLazyBody(uint64_t Offset) { Body = Offset; }
4835456b0fe40714a78cd0ba7c1a5b7dc34eda385afDouglas Gregor
4845456b0fe40714a78cd0ba7c1a5b7dc34eda385afDouglas Gregor  CompoundStmt *getCompoundBody() { return (CompoundStmt*)getBody(); }
485d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  void setBody(Stmt *B) { Body = B; }
48658dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff
48766570b230941651245accbc5680b60e904eb993cArgyrios Kyrtzidis  /// \brief Returns whether this specific method is a definition.
4887247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie  bool isThisDeclarationADefinition() const { return hasBody(); }
48966570b230941651245accbc5680b60e904eb993cArgyrios Kyrtzidis
49058dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  // Implement isa/cast/dyncast/etc.
49180cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
49280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ObjCMethod; }
49342220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis  static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
49442220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis    return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
49542220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis  }
49642220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis  static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) {
49742220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis    return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC));
49842220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis  }
499491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
500491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  friend class ASTDeclReader;
501491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  friend class ASTDeclWriter;
50258dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff};
503e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff
504e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff/// ObjCContainerDecl - Represents a container for method declarations.
505aecae629269fae3bf484baf1d109e9a89d14eeadArgyrios Kyrtzidis/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
5061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ObjCProtocolDecl, and ObjCImplDecl.
507e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff///
5084afa39deaa245592977136d367251ee2c173dd8dDouglas Gregorclass ObjCContainerDecl : public NamedDecl, public DeclContext {
509651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void anchor() override;
51099ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
5111711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis  SourceLocation AtStart;
5121711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis
513782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek  // These two locations in the range mark the end of the method container.
514782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek  // The first points to the '@' token, and the second to the 'end' token.
515782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek  SourceRange AtEnd;
516e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroffpublic:
517e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff
5181711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis  ObjCContainerDecl(Kind DK, DeclContext *DC,
5191711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                    IdentifierInfo *Id, SourceLocation nameLoc,
5201711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                    SourceLocation atStartLoc)
5211711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis    : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {}
522e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff
52393983f8fa120330bf212bfde7e65da2709fb3be8Steve Naroff  // Iterator access to properties.
52493983f8fa120330bf212bfde7e65da2709fb3be8Steve Naroff  typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
525651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>>
526651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    prop_range;
527651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
528651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  prop_range properties() const { return prop_range(prop_begin(), prop_end()); }
5291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  prop_iterator prop_begin() const {
53017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return prop_iterator(decls_begin());
53193983f8fa120330bf212bfde7e65da2709fb3be8Steve Naroff  }
5321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  prop_iterator prop_end() const {
53317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return prop_iterator(decls_end());
53409c4719788a5cea09897525e528fa00420f1677bSteve Naroff  }
5351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5360701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  // Iterator access to instance/class methods.
537f8d49f64ef6ab7e632717a31631fc289aab69428Douglas Gregor  typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
538651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>>
539651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    method_range;
540651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
541651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  method_range methods() const {
542651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return method_range(meth_begin(), meth_end());
543651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
5441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  method_iterator meth_begin() const {
54517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return method_iterator(decls_begin());
5467ed4faca5162b3ab85be7f7e57aa40e6ec170971Ted Kremenek  }
5471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  method_iterator meth_end() const {
54817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return method_iterator(decls_end());
5497ed4faca5162b3ab85be7f7e57aa40e6ec170971Ted Kremenek  }
5500701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff
5511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  typedef filtered_decl_iterator<ObjCMethodDecl,
5521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                 &ObjCMethodDecl::isInstanceMethod>
553669c9a28fa4be35e6b6322aa7f2f3b2968189b80Douglas Gregor    instmeth_iterator;
554651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<instmeth_iterator> instmeth_range;
555651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
556651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  instmeth_range instance_methods() const {
557651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return instmeth_range(instmeth_begin(), instmeth_end());
558651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
55917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  instmeth_iterator instmeth_begin() const {
56017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return instmeth_iterator(decls_begin());
561e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff  }
56217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  instmeth_iterator instmeth_end() const {
56317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return instmeth_iterator(decls_end());
564e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff  }
565e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff
5661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  typedef filtered_decl_iterator<ObjCMethodDecl,
5671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                 &ObjCMethodDecl::isClassMethod>
568669c9a28fa4be35e6b6322aa7f2f3b2968189b80Douglas Gregor    classmeth_iterator;
569651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<classmeth_iterator> classmeth_range;
570651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
571651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  classmeth_range class_methods() const {
572651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return classmeth_range(classmeth_begin(), classmeth_end());
573651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
57417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  classmeth_iterator classmeth_begin() const {
57517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return classmeth_iterator(decls_begin());
576e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff  }
57717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  classmeth_iterator classmeth_end() const {
57817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return classmeth_iterator(decls_end());
5790701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  }
5800701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff
5810701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  // Get the local instance/class method declared in this interface.
58204593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis  ObjCMethodDecl *getMethod(Selector Sel, bool isInstance,
58304593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis                            bool AllowHidden = false) const;
58404593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis  ObjCMethodDecl *getInstanceMethod(Selector Sel,
58504593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis                                    bool AllowHidden = false) const {
58604593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis    return getMethod(Sel, true/*isInstance*/, AllowHidden);
58704593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis  }
58804593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis  ObjCMethodDecl *getClassMethod(Selector Sel, bool AllowHidden = false) const {
58904593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis    return getMethod(Sel, false/*isInstance*/, AllowHidden);
590467c0b165072689ef87fe8d9cd47a5b63485bcdcArgyrios Kyrtzidis  }
5915bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian  bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const;
592467c0b165072689ef87fe8d9cd47a5b63485bcdcArgyrios Kyrtzidis  ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
5931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
594176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  ObjCPropertyDecl *
595176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  FindPropertyDeclaration(const IdentifierInfo *PropertyId) const;
59693983f8fa120330bf212bfde7e65da2709fb3be8Steve Naroff
597e63aedd0cb064fc106636ad856cc0e645e6374ceAnna Zaks  typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap;
598cfaed8d399a34e79fbab9f70eb4ea1bbeb81a02bFariborz Jahanian
5998dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian  typedef llvm::DenseMap<const ObjCProtocolDecl *, ObjCPropertyDecl*>
6008dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian            ProtocolPropertyMap;
6018dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian
602cfaed8d399a34e79fbab9f70eb4ea1bbeb81a02bFariborz Jahanian  typedef llvm::SmallVector<ObjCPropertyDecl*, 8> PropertyDeclOrder;
603cfaed8d399a34e79fbab9f70eb4ea1bbeb81a02bFariborz Jahanian
604b36ea375e20f71df19c101fa2399b7ea3a607e04Anna Zaks  /// This routine collects list of properties to be implemented in the class.
605b36ea375e20f71df19c101fa2399b7ea3a607e04Anna Zaks  /// This includes, class's and its conforming protocols' properties.
606e63aedd0cb064fc106636ad856cc0e645e6374ceAnna Zaks  /// Note, the superclass's properties are not included in the list.
607cfaed8d399a34e79fbab9f70eb4ea1bbeb81a02bFariborz Jahanian  virtual void collectPropertiesToImplement(PropertyMap &PM,
608cfaed8d399a34e79fbab9f70eb4ea1bbeb81a02bFariborz Jahanian                                            PropertyDeclOrder &PO) const {}
609b36ea375e20f71df19c101fa2399b7ea3a607e04Anna Zaks
6101711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis  SourceLocation getAtStartLoc() const { return AtStart; }
6111711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis  void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; }
6121711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis
613e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff  // Marks the end of the container.
614782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek  SourceRange getAtEndRange() const {
615782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek    return AtEnd;
616782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek  }
617782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek  void setAtEndRange(SourceRange atEnd) {
618782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek    AtEnd = atEnd;
619782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek  }
620ddfd4c9eda34765b08fae4cb31ad5a365face107Argyrios Kyrtzidis
621651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SourceRange getSourceRange() const override LLVM_READONLY {
6221711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis    return SourceRange(AtStart, getAtEndRange().getEnd());
623ddfd4c9eda34765b08fae4cb31ad5a365face107Argyrios Kyrtzidis  }
6241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62509c4719788a5cea09897525e528fa00420f1677bSteve Naroff  // Implement isa/cast/dyncast/etc.
62680cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
62780cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
6289a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt    return K >= firstObjCContainer &&
6299a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt           K <= lastObjCContainer;
63080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  }
63109c4719788a5cea09897525e528fa00420f1677bSteve Naroff
63209c4719788a5cea09897525e528fa00420f1677bSteve Naroff  static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
63309c4719788a5cea09897525e528fa00420f1677bSteve Naroff    return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
63409c4719788a5cea09897525e528fa00420f1677bSteve Naroff  }
63509c4719788a5cea09897525e528fa00420f1677bSteve Naroff  static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) {
63609c4719788a5cea09897525e528fa00420f1677bSteve Naroff    return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC));
63709c4719788a5cea09897525e528fa00420f1677bSteve Naroff  }
638e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff};
639e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff
6400982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// \brief Represents an ObjC class declaration.
6410c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
6420982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// For example:
6430982205bade2fb4fc984c27b2ab401e683963b10James Dennett///
6440982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// \code
6450c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   // MostPrimitive declares no super class (not particularly useful).
64641c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth///   \@interface MostPrimitive
6470c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     // no instance variables or methods.
64841c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth///   \@end
6490c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
6501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///   // NSResponder inherits from NSObject & implements NSCoding (a protocol).
6510982205bade2fb4fc984c27b2ab401e683963b10James Dennett///   \@interface NSResponder : NSObject \<NSCoding>
652a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek///   { // instance variables are represented by ObjCIvarDecl.
6530c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id nextResponder; // nextResponder instance variable.
6540c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   }
6550c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   - (NSResponder *)nextResponder; // return a pointer to NSResponder.
6560c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
65741c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth///   \@end                                    // to an NSEvent.
6580982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// \endcode
6590c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
66041c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth///   Unlike C/C++, forward class declarations are accomplished with \@class.
66141c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth///   Unlike C/C++, \@class allows for a list of classes to be forward declared.
6620c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
6630c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   typically inherit from NSObject (an exception is NSProxy).
6640c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
66553df7a1d34f21d8f2309311d1067d463e9064c60Douglas Gregorclass ObjCInterfaceDecl : public ObjCContainerDecl
66653df7a1d34f21d8f2309311d1067d463e9064c60Douglas Gregor                        , public Redeclarable<ObjCInterfaceDecl> {
667651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void anchor() override;
66899ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
6693110251f13981689f384eb3c0aba2afffea18d9dSteve Naroff  /// TypeForDecl - This indicates the Type object that represents this
6703110251f13981689f384eb3c0aba2afffea18d9dSteve Naroff  /// TypeDecl.  It is a cache maintained by ASTContext::getObjCInterfaceType
671f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  mutable const Type *TypeForDecl;
6723110251f13981689f384eb3c0aba2afffea18d9dSteve Naroff  friend class ASTContext;
6732e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
6742e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  struct DefinitionData {
67526fec63b14565e9e2d8c9935b276b99be950444aDouglas Gregor    /// \brief The definition of this class, for quick access from any
67626fec63b14565e9e2d8c9935b276b99be950444aDouglas Gregor    /// declaration.
67726fec63b14565e9e2d8c9935b276b99be950444aDouglas Gregor    ObjCInterfaceDecl *Definition;
67826fec63b14565e9e2d8c9935b276b99be950444aDouglas Gregor
6792e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    /// Class's super class.
6802e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    ObjCInterfaceDecl *SuperClass;
6811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
68241c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth    /// Protocols referenced in the \@interface  declaration
6832e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    ObjCProtocolList ReferencedProtocols;
6841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
68541c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth    /// Protocols reference in both the \@interface and class extensions.
6862e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    ObjCList<ObjCProtocolDecl> AllReferencedProtocols;
687ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
6882e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    /// \brief List of categories and class extensions defined for this class.
6892e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    ///
6902e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    /// Categories are stored as a linked list in the AST, since the categories
6912e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    /// and class extensions come long after the initial interface declaration,
6922e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    /// and we avoid dynamically-resized arrays in the AST wherever possible.
6932e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    ObjCCategoryDecl *CategoryList;
6941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6952e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    /// IvarList - List of all ivars defined by this class; including class
6962e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    /// extensions and implementation. This list is built lazily.
6972e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    ObjCIvarDecl *IvarList;
698ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
6992e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    /// \brief Indicates that the contents of this Objective-C class will be
7002e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    /// completed by the external AST source when required.
7012e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    mutable bool ExternallyCompleted : 1;
7022e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
7034919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl    /// \brief Indicates that the ivar cache does not yet include ivars
7044919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl    /// declared in the implementation.
7054919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl    mutable bool IvarListMissingImplementation : 1;
7064919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl
707651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// Indicates that this interface decl contains at least one initializer
708651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// marked with the 'objc_designated_initializer' attribute.
709651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    bool HasDesignatedInitializers : 1;
710651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
711651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    enum InheritedDesignatedInitializersState {
712651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      /// We didn't calculate whether the designated initializers should be
713651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      /// inherited or not.
714651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      IDI_Unknown = 0,
715651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      /// Designated initializers are inherited for the super class.
716651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      IDI_Inherited = 1,
717651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      /// The class does not inherit designated initializers.
718651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      IDI_NotInherited = 2
719651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    };
720651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// One of the \c InheritedDesignatedInitializersState enumeratos.
721651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    mutable unsigned InheritedDesignatedInitializers : 2;
722651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
72305c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor    /// \brief The location of the superclass, if any.
72405c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor    SourceLocation SuperClassLoc;
725161794732195881c33305f701f6e58721998541fDouglas Gregor
72605c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor    /// \brief The location of the last location in this declaration, before
72705c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor    /// the properties/methods. For example, this will be the '>', '}', or
72805c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor    /// identifier,
72905c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor    SourceLocation EndLoc;
73005c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor
73126fec63b14565e9e2d8c9935b276b99be950444aDouglas Gregor    DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(),
7324919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl                       ExternallyCompleted(),
733651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                       IvarListMissingImplementation(true),
734651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                       HasDesignatedInitializers(),
735651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                       InheritedDesignatedInitializers(IDI_Unknown) { }
7362e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  };
7372e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
7386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
7396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                    IdentifierInfo *Id, SourceLocation CLoc,
7406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                    ObjCInterfaceDecl *PrevDecl, bool IsInternal);
7412e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
7422e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  void LoadExternalDefinition() const;
7432e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
7442e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  /// \brief Contains a pointer to the data associated with this class,
7452e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  /// which will be NULL if this class has not yet been defined.
7466bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  ///
7476bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  /// The bit indicates when we don't need to check for out-of-date
7486bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  /// declarations. It will be set unless modules are enabled.
7496bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  llvm::PointerIntPair<DefinitionData *, 1, bool> Data;
7502e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
7512e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  DefinitionData &data() const {
7526bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    assert(Data.getPointer() && "Declaration has no definition!");
7536bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    return *Data.getPointer();
7542e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  }
7551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7562e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  /// \brief Allocate the definition data for this class.
7572e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  void allocateDefinitionData();
7582e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
75953df7a1d34f21d8f2309311d1067d463e9064c60Douglas Gregor  typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
7606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCInterfaceDecl *getNextRedeclarationImpl() override {
7616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return getNextRedeclaration();
76253df7a1d34f21d8f2309311d1067d463e9064c60Douglas Gregor  }
763651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ObjCInterfaceDecl *getPreviousDeclImpl() override {
764ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor    return getPreviousDecl();
765ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  }
766651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ObjCInterfaceDecl *getMostRecentDeclImpl() override {
767ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor    return getMostRecentDecl();
768ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  }
76953df7a1d34f21d8f2309311d1067d463e9064c60Douglas Gregor
7700e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattnerpublic:
771a6ea10e22b600d92e084f6b11b9b9a92d0eb2412Douglas Gregor  static ObjCInterfaceDecl *Create(const ASTContext &C, DeclContext *DC,
7720ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner                                   SourceLocation atLoc,
7731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                   IdentifierInfo *Id,
7740af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor                                   ObjCInterfaceDecl *PrevDecl,
775deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor                                   SourceLocation ClassLoc = SourceLocation(),
7760e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner                                   bool isInternal = false);
777d1cf3ff6c7e34fce764293cd2900fce99a60ed69Argyrios Kyrtzidis
7786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
7790af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor
780651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SourceRange getSourceRange() const override LLVM_READONLY {
7817723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor    if (isThisDeclarationADefinition())
7827723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor      return ObjCContainerDecl::getSourceRange();
7837723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor
7847723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor    return SourceRange(getAtStartLoc(), getLocation());
785d1cf3ff6c7e34fce764293cd2900fce99a60ed69Argyrios Kyrtzidis  }
786ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
78726ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor  /// \brief Indicate that this Objective-C class is complete, but that
78826ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor  /// the external AST source will be responsible for filling in its contents
78926ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor  /// when a complete class is required.
79026ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor  void setExternallyCompleted();
791ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
792651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Indicate that this interface decl contains at least one initializer
793651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// marked with the 'objc_designated_initializer' attribute.
794651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void setHasDesignatedInitializers();
795651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
796651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Returns true if this interface decl contains at least one initializer
797651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// marked with the 'objc_designated_initializer' attribute.
798651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool hasDesignatedInitializers() const;
799651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
800651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Returns true if this interface decl declares a designated initializer
801651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// or it inherites one from its super class.
802651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool declaresOrInheritsDesignatedInitializers() const {
803651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return hasDesignatedInitializers() || inheritsDesignatedInitializers();
804651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
805651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
80618df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  const ObjCProtocolList &getReferencedProtocols() const {
807a5f4441de7890953460d95f4e88b9fa432b48dc2Argyrios Kyrtzidis    assert(hasDefinition() && "Caller did not check for forward reference!");
8082e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (data().ExternallyCompleted)
80926ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor      LoadExternalDefinition();
810ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
8112e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    return data().ReferencedProtocols;
8127ed9e0f97f4645edc5d4670385b985ea4c617ce7Fariborz Jahanian  }
8138a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
8148a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  ObjCImplementationDecl *getImplementation() const;
8158a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  void setImplementation(ObjCImplementationDecl *ImplD);
8168a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
817559c0c4bbecc017aab0716d546c4fefbcc194687Fariborz Jahanian  ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
8181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8191cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis  // Get the local instance/class method declared in a category.
8201cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis  ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const;
8211cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis  ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const;
8221cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis  ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const {
8233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    return isInstance ? getCategoryInstanceMethod(Sel)
8243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                      : getCategoryClassMethod(Sel);
8251cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis  }
8263db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner
82718df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  typedef ObjCProtocolList::iterator protocol_iterator;
828651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<protocol_iterator> protocol_range;
829ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
830651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  protocol_range protocols() const {
831651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return protocol_range(protocol_begin(), protocol_end());
832651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
83353b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek  protocol_iterator protocol_begin() const {
8342e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    // FIXME: Should make sure no callers ever do this.
8352e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (!hasDefinition())
8362e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor      return protocol_iterator();
8372e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
8382e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (data().ExternallyCompleted)
83926ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor      LoadExternalDefinition();
84026ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor
8412e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    return data().ReferencedProtocols.begin();
84253b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek  }
84353b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek  protocol_iterator protocol_end() const {
8442e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    // FIXME: Should make sure no callers ever do this.
8452e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (!hasDefinition())
8462e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor      return protocol_iterator();
8472e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
8482e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (data().ExternallyCompleted)
84926ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor      LoadExternalDefinition();
85026ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor
8512e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    return data().ReferencedProtocols.end();
85253b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek  }
85353b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek
85418df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
855651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
85653b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek
857651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  protocol_loc_range protocol_locs() const {
858651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
859651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
860ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  protocol_loc_iterator protocol_loc_begin() const {
8612e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    // FIXME: Should make sure no callers ever do this.
8622e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (!hasDefinition())
8632e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor      return protocol_loc_iterator();
8642e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
8652e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (data().ExternallyCompleted)
86626ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor      LoadExternalDefinition();
86726ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor
8682e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    return data().ReferencedProtocols.loc_begin();
86918df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  }
87053b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek
871ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  protocol_loc_iterator protocol_loc_end() const {
8722e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    // FIXME: Should make sure no callers ever do this.
8732e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (!hasDefinition())
8742e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor      return protocol_loc_iterator();
8752e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
8762e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (data().ExternallyCompleted)
87726ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor      LoadExternalDefinition();
87826ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor
8792e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    return data().ReferencedProtocols.loc_end();
88018df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  }
881ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
88253b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek  typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator;
883651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<all_protocol_iterator> all_protocol_range;
884ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
885651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  all_protocol_range all_referenced_protocols() const {
886651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return all_protocol_range(all_referenced_protocol_begin(),
887651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                              all_referenced_protocol_end());
888651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
88953b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek  all_protocol_iterator all_referenced_protocol_begin() const {
8902e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    // FIXME: Should make sure no callers ever do this.
8912e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (!hasDefinition())
8922e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor      return all_protocol_iterator();
8932e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
8942e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (data().ExternallyCompleted)
89526ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor      LoadExternalDefinition();
89626ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor
8972e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    return data().AllReferencedProtocols.empty()
8982e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor             ? protocol_begin()
8992e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor             : data().AllReferencedProtocols.begin();
90053b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek  }
90153b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek  all_protocol_iterator all_referenced_protocol_end() const {
9022e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    // FIXME: Should make sure no callers ever do this.
9032e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (!hasDefinition())
9042e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor      return all_protocol_iterator();
9052e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
9062e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (data().ExternallyCompleted)
90726ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor      LoadExternalDefinition();
90826ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor
9092e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    return data().AllReferencedProtocols.empty()
9102e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor             ? protocol_end()
9112e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor             : data().AllReferencedProtocols.end();
91253b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek  }
913291be393aa33759e6e34b6429c5ffa206ba50115Douglas Gregor
91411062e11236b7bc689dad150e8b490fd6b063ec3Fariborz Jahanian  typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
915651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
91653b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek
917651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
9182e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  ivar_iterator ivar_begin() const {
9192e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (const ObjCInterfaceDecl *Def = getDefinition())
9202e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor      return ivar_iterator(Def->decls_begin());
9212e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
9222e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    // FIXME: Should make sure no callers ever do this.
9232e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    return ivar_iterator();
9242e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  }
9252e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  ivar_iterator ivar_end() const {
9262e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (const ObjCInterfaceDecl *Def = getDefinition())
9272e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor      return ivar_iterator(Def->decls_end());
9282e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
9292e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    // FIXME: Should make sure no callers ever do this.
9302e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    return ivar_iterator();
9312e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  }
93253b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek
93311062e11236b7bc689dad150e8b490fd6b063ec3Fariborz Jahanian  unsigned ivar_size() const {
93411062e11236b7bc689dad150e8b490fd6b063ec3Fariborz Jahanian    return std::distance(ivar_begin(), ivar_end());
93511062e11236b7bc689dad150e8b490fd6b063ec3Fariborz Jahanian  }
936ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
93711062e11236b7bc689dad150e8b490fd6b063ec3Fariborz Jahanian  bool ivar_empty() const { return ivar_begin() == ivar_end(); }
938ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
939db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  ObjCIvarDecl *all_declared_ivar_begin();
940db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const ObjCIvarDecl *all_declared_ivar_begin() const {
941db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose    // Even though this modifies IvarList, it's conceptually const:
942db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose    // the ivar chain is essentially a cached property of ObjCInterfaceDecl.
943db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose    return const_cast<ObjCInterfaceDecl *>(this)->all_declared_ivar_begin();
944db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  }
9452e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  void setIvarList(ObjCIvarDecl *ivar) { data().IvarList = ivar; }
946ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
94738af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  /// setProtocolList - Set the list of protocols that this interface
948b752f289026ad8e5f44851b20e009a27ed61eefcChris Lattner  /// implements.
94938af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
95018df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor                       const SourceLocation *Locs, ASTContext &C) {
9512e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    data().ReferencedProtocols.set(List, Num, Locs, C);
9523db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  }
9531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
954339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian  /// mergeClassExtensionProtocolList - Merge class extension's protocol list
955339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian  /// into the protocol list for this class.
956ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List,
95718df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor                                       unsigned Num,
95818df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor                                       ASTContext &C);
959339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian
960176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// Produce a name to be used for class's metadata. It comes either via
961176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// objc_runtime_name attribute or class name.
962176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  StringRef getObjCRuntimeNameAsString() const;
963176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
964651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Returns the designated initializers for the interface.
965651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///
966651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// If this declaration does not have methods marked as designated
967651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// initializers then the interface inherits the designated initializers of
968651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// its super class.
969651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void getDesignatedInitializers(
970651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                  llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const;
971651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
972651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Returns true if the given selector is a designated initializer for the
973651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// interface.
974651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///
975651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// If this declaration does not have methods marked as designated
976651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// initializers then the interface inherits the designated initializers of
977651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// its super class.
978651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///
979651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \param InitMethod if non-null and the function returns true, it receives
980651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// the method that was marked as a designated initializer.
9816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool
9826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  isDesignatedInitializer(Selector Sel,
9836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                          const ObjCMethodDecl **InitMethod = nullptr) const;
984651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
98553df7a1d34f21d8f2309311d1067d463e9064c60Douglas Gregor  /// \brief Determine whether this particular declaration of this class is
98653df7a1d34f21d8f2309311d1067d463e9064c60Douglas Gregor  /// actually also a definition.
98726fec63b14565e9e2d8c9935b276b99be950444aDouglas Gregor  bool isThisDeclarationADefinition() const {
9886bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    return getDefinition() == this;
98926fec63b14565e9e2d8c9935b276b99be950444aDouglas Gregor  }
99053df7a1d34f21d8f2309311d1067d463e9064c60Douglas Gregor
9912e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  /// \brief Determine whether this class has been defined.
9926bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  bool hasDefinition() const {
9936bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    // If the name of this class is out-of-date, bring it up-to-date, which
9946bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    // might bring in a definition.
9956bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    // Note: a null value indicates that we don't have a definition and that
9966bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    // modules are enabled.
9976bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    if (!Data.getOpaqueValue()) {
9986bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor      if (IdentifierInfo *II = getIdentifier()) {
9996bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor        if (II->isOutOfDate()) {
10006bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor          updateOutOfDate(*II);
10016bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor        }
10026bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor      }
10036bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    }
10046bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor
10056bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    return Data.getPointer();
10066bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  }
100753df7a1d34f21d8f2309311d1067d463e9064c60Douglas Gregor
10082e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  /// \brief Retrieve the definition of this class, or NULL if this class
100941c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// has been forward-declared (with \@class) but not yet defined (with
101041c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// \@interface).
10112e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  ObjCInterfaceDecl *getDefinition() {
10126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return hasDefinition()? Data.getPointer()->Definition : nullptr;
10132e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  }
1014ad834d534e9a5db3d3baa09593775f83ceaff1f2Argyrios Kyrtzidis
10152e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  /// \brief Retrieve the definition of this class, or NULL if this class
101641c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// has been forward-declared (with \@class) but not yet defined (with
101741c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// \@interface).
10182e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  const ObjCInterfaceDecl *getDefinition() const {
10196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return hasDefinition()? Data.getPointer()->Definition : nullptr;
10202e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  }
10211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10222e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  /// \brief Starts the definition of this Objective-C class, taking it from
102341c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// a forward declaration (\@class) to a definition (\@interface).
10242e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  void startDefinition();
10252e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
1026ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  ObjCInterfaceDecl *getSuperClass() const {
10272e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    // FIXME: Should make sure no callers ever do this.
10282e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (!hasDefinition())
10296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return nullptr;
10302e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
10312e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (data().ExternallyCompleted)
103226ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor      LoadExternalDefinition();
103326ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor
10342e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    return data().SuperClass;
103526ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor  }
1036ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
10372e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  void setSuperClass(ObjCInterfaceDecl * superCls) {
1038712ef874534ee1bef41d1aa4664ae36148ec8b12Fariborz Jahanian    data().SuperClass =
1039712ef874534ee1bef41d1aa4664ae36148ec8b12Fariborz Jahanian      (superCls && superCls->hasDefinition()) ? superCls->getDefinition()
1040712ef874534ee1bef41d1aa4664ae36148ec8b12Fariborz Jahanian                                              : superCls;
10412e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  }
10421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1043d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Iterator that walks over the list of categories, filtering out
1044d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// those that do not meet specific criteria.
1045d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  ///
1046d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// This class template is used for the various permutations of category
1047d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// and extension iterators.
1048d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  template<bool (*Filter)(ObjCCategoryDecl *)>
1049d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  class filtered_category_iterator {
1050d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    ObjCCategoryDecl *Current;
1051d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1052d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    void findAcceptableCategory();
1053d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1054d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  public:
1055d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    typedef ObjCCategoryDecl *      value_type;
1056d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    typedef value_type              reference;
1057d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    typedef value_type              pointer;
1058d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    typedef std::ptrdiff_t          difference_type;
1059d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    typedef std::input_iterator_tag iterator_category;
1060d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
10616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    filtered_category_iterator() : Current(nullptr) { }
1062d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    explicit filtered_category_iterator(ObjCCategoryDecl *Current)
1063d329724745b49f894b768d47275b7c2713106e89Douglas Gregor      : Current(Current)
1064d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    {
1065d329724745b49f894b768d47275b7c2713106e89Douglas Gregor      findAcceptableCategory();
1066d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    }
1067d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1068d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    reference operator*() const { return Current; }
1069d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    pointer operator->() const { return Current; }
1070d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1071d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    filtered_category_iterator &operator++();
1072d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1073d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    filtered_category_iterator operator++(int) {
1074d329724745b49f894b768d47275b7c2713106e89Douglas Gregor      filtered_category_iterator Tmp = *this;
1075d329724745b49f894b768d47275b7c2713106e89Douglas Gregor      ++(*this);
1076d329724745b49f894b768d47275b7c2713106e89Douglas Gregor      return Tmp;
1077d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    }
1078d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1079d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    friend bool operator==(filtered_category_iterator X,
1080d329724745b49f894b768d47275b7c2713106e89Douglas Gregor                           filtered_category_iterator Y) {
10811c2397539d1b105eacee2a69ece4775d0af45618Matt Beaumont-Gay      return X.Current == Y.Current;
1082d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    }
1083d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1084d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    friend bool operator!=(filtered_category_iterator X,
1085d329724745b49f894b768d47275b7c2713106e89Douglas Gregor                           filtered_category_iterator Y) {
1086d329724745b49f894b768d47275b7c2713106e89Douglas Gregor      return X.Current != Y.Current;
1087d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    }
1088d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  };
1089d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1090d329724745b49f894b768d47275b7c2713106e89Douglas Gregorprivate:
1091d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Test whether the given category is visible.
1092d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  ///
1093d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// Used in the \c visible_categories_iterator.
1094d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  static bool isVisibleCategory(ObjCCategoryDecl *Cat);
1095d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1096d329724745b49f894b768d47275b7c2713106e89Douglas Gregorpublic:
1097d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Iterator that walks over the list of categories and extensions
1098d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// that are visible, i.e., not hidden in a non-imported submodule.
1099d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  typedef filtered_category_iterator<isVisibleCategory>
1100d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    visible_categories_iterator;
1101d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<visible_categories_iterator>
1103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    visible_categories_range;
1104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  visible_categories_range visible_categories() const {
1106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return visible_categories_range(visible_categories_begin(),
1107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    visible_categories_end());
1108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
1109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1110d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Retrieve an iterator to the beginning of the visible-categories
1111d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// list.
1112d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  visible_categories_iterator visible_categories_begin() const {
1113d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    return visible_categories_iterator(getCategoryListRaw());
1114d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  }
1115d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1116d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Retrieve an iterator to the end of the visible-categories list.
1117d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  visible_categories_iterator visible_categories_end() const {
1118d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    return visible_categories_iterator();
1119d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  }
1120d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1121d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Determine whether the visible-categories list is empty.
1122d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  bool visible_categories_empty() const {
1123d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    return visible_categories_begin() == visible_categories_end();
1124d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  }
1125d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1126d329724745b49f894b768d47275b7c2713106e89Douglas Gregorprivate:
1127d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Test whether the given category... is a category.
1128d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  ///
1129d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// Used in the \c known_categories_iterator.
1130d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  static bool isKnownCategory(ObjCCategoryDecl *) { return true; }
1131d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1132d329724745b49f894b768d47275b7c2713106e89Douglas Gregorpublic:
1133d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Iterator that walks over all of the known categories and
1134d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// extensions, including those that are hidden.
1135d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  typedef filtered_category_iterator<isKnownCategory> known_categories_iterator;
1136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<known_categories_iterator>
1137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    known_categories_range;
1138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  known_categories_range known_categories() const {
1140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return known_categories_range(known_categories_begin(),
1141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                  known_categories_end());
1142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
1143d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1144d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Retrieve an iterator to the beginning of the known-categories
1145d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// list.
1146d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  known_categories_iterator known_categories_begin() const {
1147d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    return known_categories_iterator(getCategoryListRaw());
1148d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  }
1149d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1150d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Retrieve an iterator to the end of the known-categories list.
1151d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  known_categories_iterator known_categories_end() const {
1152d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    return known_categories_iterator();
1153d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  }
1154d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1155d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Determine whether the known-categories list is empty.
1156d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  bool known_categories_empty() const {
1157d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    return known_categories_begin() == known_categories_end();
1158d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  }
1159d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1160d329724745b49f894b768d47275b7c2713106e89Douglas Gregorprivate:
1161d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Test whether the given category is a visible extension.
1162d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  ///
1163d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// Used in the \c visible_extensions_iterator.
1164d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  static bool isVisibleExtension(ObjCCategoryDecl *Cat);
1165d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1166d329724745b49f894b768d47275b7c2713106e89Douglas Gregorpublic:
1167d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Iterator that walks over all of the visible extensions, skipping
1168d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// any that are known but hidden.
1169d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  typedef filtered_category_iterator<isVisibleExtension>
1170d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    visible_extensions_iterator;
1171d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<visible_extensions_iterator>
1173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    visible_extensions_range;
1174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  visible_extensions_range visible_extensions() const {
1176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return visible_extensions_range(visible_extensions_begin(),
1177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    visible_extensions_end());
1178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
1179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1180d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Retrieve an iterator to the beginning of the visible-extensions
1181d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// list.
1182d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  visible_extensions_iterator visible_extensions_begin() const {
1183d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    return visible_extensions_iterator(getCategoryListRaw());
1184d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  }
1185d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1186d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Retrieve an iterator to the end of the visible-extensions list.
1187d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  visible_extensions_iterator visible_extensions_end() const {
1188d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    return visible_extensions_iterator();
1189d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  }
1190d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1191d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Determine whether the visible-extensions list is empty.
1192d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  bool visible_extensions_empty() const {
1193d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    return visible_extensions_begin() == visible_extensions_end();
1194d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  }
1195d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1196d329724745b49f894b768d47275b7c2713106e89Douglas Gregorprivate:
1197d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Test whether the given category is an extension.
1198d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  ///
1199d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// Used in the \c known_extensions_iterator.
1200d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  static bool isKnownExtension(ObjCCategoryDecl *Cat);
1201d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1202d329724745b49f894b768d47275b7c2713106e89Douglas Gregorpublic:
1203d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Iterator that walks over all of the known extensions.
1204d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  typedef filtered_category_iterator<isKnownExtension>
1205d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    known_extensions_iterator;
1206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<known_extensions_iterator>
1207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    known_extensions_range;
1208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  known_extensions_range known_extensions() const {
1210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return known_extensions_range(known_extensions_begin(),
1211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                  known_extensions_end());
1212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
1213d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1214d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Retrieve an iterator to the beginning of the known-extensions
1215d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// list.
1216d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  known_extensions_iterator known_extensions_begin() const {
1217d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    return known_extensions_iterator(getCategoryListRaw());
1218d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  }
1219d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1220d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Retrieve an iterator to the end of the known-extensions list.
1221d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  known_extensions_iterator known_extensions_end() const {
1222d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    return known_extensions_iterator();
1223d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  }
1224d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1225d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Determine whether the known-extensions list is empty.
1226d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  bool known_extensions_empty() const {
1227d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    return known_extensions_begin() == known_extensions_end();
1228d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  }
1229d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1230d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Retrieve the raw pointer to the start of the category/extension
1231d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// list.
1232d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  ObjCCategoryDecl* getCategoryListRaw() const {
12332e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    // FIXME: Should make sure no callers ever do this.
12342e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (!hasDefinition())
12356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return nullptr;
12362e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
12372e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (data().ExternallyCompleted)
123826ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor      LoadExternalDefinition();
123926ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor
12402e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    return data().CategoryList;
124126ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor  }
1242ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1243d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Set the raw pointer to the start of the category/extension
1244d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// list.
1245d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  void setCategoryListRaw(ObjCCategoryDecl *category) {
12462e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    data().CategoryList = category;
1247980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
1248ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
124937cafb077ad5b170acae77e566638603011ef4c0Ted Kremenek  ObjCPropertyDecl
125037cafb077ad5b170acae77e566638603011ef4c0Ted Kremenek    *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
125137cafb077ad5b170acae77e566638603011ef4c0Ted Kremenek
1252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void collectPropertiesToImplement(PropertyMap &PM,
1253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    PropertyDeclOrder &PO) const override;
1254b36ea375e20f71df19c101fa2399b7ea3a607e04Anna Zaks
125553efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner  /// isSuperClassOf - Return true if this class is the specified class or is a
125653efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner  /// super class of the specified interface class.
125753efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner  bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
125853efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner    // If RHS is derived from LHS it is OK; else it is not OK.
12596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    while (I != nullptr) {
126060ef308e51c71b760d7f598c1b763ceb7b768148Douglas Gregor      if (declaresSameEntity(this, I))
126153efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner        return true;
12622e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
126353efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner      I = I->getSuperClass();
126453efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner    }
126553efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner    return false;
126653efc251792bf2c9c5f295bd3507facc51a1fe7eChris Lattner  }
12671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12687263feeb367ab55af7e9a6fd701148b1b8264dbaFariborz Jahanian  /// isArcWeakrefUnavailable - Checks for a class or one of its super classes
12697263feeb367ab55af7e9a6fd701148b1b8264dbaFariborz Jahanian  /// to be incompatible with __weak references. Returns true if it is.
12702fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer  bool isArcWeakrefUnavailable() const;
12717263feeb367ab55af7e9a6fd701148b1b8264dbaFariborz Jahanian
127271207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek  /// isObjCRequiresPropertyDefs - Checks that a class or one of its super
127341c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// classes must not be auto-synthesized. Returns class decl. if it must not
127441c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// be; 0, otherwise.
12752fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer  const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const;
1276e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian
127717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
127868a057b4292f5ff814ec8da53f6cda8cdcfbd2aeChris Lattner                                       ObjCInterfaceDecl *&ClassDeclared);
127917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
128068a057b4292f5ff814ec8da53f6cda8cdcfbd2aeChris Lattner    ObjCInterfaceDecl *ClassDeclared;
128117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return lookupInstanceVariable(IVarName, ClassDeclared);
128268a057b4292f5ff814ec8da53f6cda8cdcfbd2aeChris Lattner  }
128368a057b4292f5ff814ec8da53f6cda8cdcfbd2aeChris Lattner
128407b1bbe648a21b8cdbc073fb6a409422c49921bbFariborz Jahanian  ObjCProtocolDecl *lookupNestedProtocol(IdentifierInfo *Name);
128507b1bbe648a21b8cdbc073fb6a409422c49921bbFariborz Jahanian
128694a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // Lookup a method. First, we search locally. If a method isn't
128794a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // found, we search referenced protocols and class categories.
1288bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian  ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
1289651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                               bool shallowCategoryLookup = false,
1290651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                               bool followSuper = true,
12916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                               const ObjCCategoryDecl *C = nullptr) const;
1292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Lookup an instance method for a given selector.
1294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
1295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return lookupMethod(Sel, true/*isInstance*/);
1296bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian  }
1297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Lookup a class method for a given selector.
1299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
1300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return lookupMethod(Sel, false/*isInstance*/);
1301aa5420c1e36ab8e0e4bb87239d8b73a3a8ce75dbArgyrios Kyrtzidis  }
1302cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian  ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
1303ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1304e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks  /// \brief Lookup a method in the classes implementation hierarchy.
1305ca93ee707d9570b74d24c7d55defe18dac38bcc0Anna Zaks  ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel,
1306ca93ee707d9570b74d24c7d55defe18dac38bcc0Anna Zaks                                      bool Instance=true) const;
130760fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff
1308e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks  ObjCMethodDecl *lookupPrivateClassMethod(const Selector &Sel) {
1309e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks    return lookupPrivateMethod(Sel, false);
1310e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks  }
1311e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks
1312f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian  /// \brief Lookup a setter or getter in the class hierarchy,
1313f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian  /// including in all categories except for category passed
1314f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian  /// as argument.
1315f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian  ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
1316f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian                                         const ObjCCategoryDecl *Cat) const {
1317f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian    return lookupMethod(Sel, true/*isInstance*/,
1318651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                        false/*shallowCategoryLookup*/,
1319651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                        true /* followsSuper */,
1320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                        Cat);
1321c775b1a0702621e297d00452a897381c8bf10f3fFariborz Jahanian  }
1322f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian
132305c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor  SourceLocation getEndOfDefinitionLoc() const {
132405c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor    if (!hasDefinition())
132505c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor      return getLocation();
132605c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor
132705c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor    return data().EndLoc;
132805c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor  }
132905c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor
133005c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor  void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; }
13311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13322e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  void setSuperClassLoc(SourceLocation Loc) { data().SuperClassLoc = Loc; }
13332e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  SourceLocation getSuperClassLoc() const { return data().SuperClassLoc; }
13341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
133528e71cf851b73a67604735a9a95aef800b144e2eSteve Naroff  /// isImplicitInterfaceDecl - check that this is an implicitly declared
133641c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// ObjCInterfaceDecl node. This is for legacy objective-c \@implementation
133741c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// declaration without an \@interface declaration.
133897bbab2df74cbfe221fb20454738d607a41f3ca4Fariborz Jahanian  bool isImplicitInterfaceDecl() const {
13396bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    return hasDefinition() ? data().Definition->isImplicit() : isImplicit();
134097bbab2df74cbfe221fb20454738d607a41f3ca4Fariborz Jahanian  }
13411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13420fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  /// ClassImplementsProtocol - Checks that 'lProto' protocol
13430fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  /// has been implemented in IDecl class, its super class or categories (if
13440fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  /// lookupCategory is true).
13450fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
13460fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian                               bool lookupCategory,
13470fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian                               bool RHSIsQualifiedID = false);
13481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1349651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef redeclarable_base::redecl_range redecl_range;
1350a54fbf2499c7cc999e22abb9be484ce976ed9689Douglas Gregor  typedef redeclarable_base::redecl_iterator redecl_iterator;
1351ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::redecls_begin;
1352ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::redecls_end;
1353651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  using redeclarable_base::redecls;
1354ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::getPreviousDecl;
1355ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::getMostRecentDecl;
13567693b32af6863c63fcaf4de087760740ee675f71Rafael Espindola  using redeclarable_base::isFirstDecl;
1357f785a7d611404cf4747287a2bbc59b4d0e6a5a8cDouglas Gregor
135853df7a1d34f21d8f2309311d1067d463e9064c60Douglas Gregor  /// Retrieves the canonical declaration of this Objective-C class.
1359651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ObjCInterfaceDecl *getCanonicalDecl() override { return getFirstDecl(); }
1360bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola  const ObjCInterfaceDecl *getCanonicalDecl() const { return getFirstDecl(); }
136153df7a1d34f21d8f2309311d1067d463e9064c60Douglas Gregor
136233feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff  // Low-level accessor
1363f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  const Type *getTypeForDecl() const { return TypeForDecl; }
1364f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }
136533feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff
136680cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
136780cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ObjCInterface; }
136853b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek
1369fc529f7fcafe7da0b8a32621e13685891e8ce52aDouglas Gregor  friend class ASTReader;
137053b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek  friend class ASTDeclReader;
137153b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek  friend class ASTDeclWriter;
1372651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1373651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesprivate:
1374651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const ObjCInterfaceDecl *findInterfaceWithDesignatedInitializers() const;
1375651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool inheritsDesignatedInitializers() const;
1376980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
1377980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
1378a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
13790c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// instance variables are identical to C. The only exception is Objective-C
13800c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// supports C++ style access control. For example:
13810c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
138241c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth///   \@interface IvarExample : NSObject
13830c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   {
1384f079570fcad0d0053e75ebae29c883ec4276e020Ted Kremenek///     id defaultToProtected;
138541c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth///   \@public:
13860c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id canBePublic; // same as C++.
138741c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth///   \@protected:
13880c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id canBeProtected; // same as C++.
138941c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth///   \@package:
13900c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///     id canBePackage; // framework visibility (not available in C++).
13910c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///   }
13920c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
1393a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekclass ObjCIvarDecl : public FieldDecl {
1394651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void anchor() override;
139599ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
13960e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattnerpublic:
1397980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  enum AccessControl {
1398980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff    None, Private, Protected, Public, Package
1399980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  };
14001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1401b8db21d4df5fbb6ce1ace6411b82d3d623d789deTed Kremenekprivate:
1402ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
1403ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara               SourceLocation IdLoc, IdentifierInfo *Id,
1404ad51e74030a59a8aa4ef0ebca1d7a701602ef53bFariborz Jahanian               QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
1405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines               bool synthesized)
1406ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara    : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
1407ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith                /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
14086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      NextIvar(nullptr), DeclAccess(ac), Synthesized(synthesized) {}
14091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1410b8db21d4df5fbb6ce1ace6411b82d3d623d789deTed Kremenekpublic:
1411a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar  static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
1412ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                              SourceLocation StartLoc, SourceLocation IdLoc,
1413ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                              IdentifierInfo *Id, QualType T,
1414a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                              TypeSourceInfo *TInfo,
14156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                              AccessControl ac, Expr *BW = nullptr,
1416651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                              bool synthesized=false);
14171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14181e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
14191e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
142027a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar  /// \brief Return the class interface that this ivar is logically contained
142127a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar  /// in; this is either the interface where the ivar was declared, or the
142227a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar  /// interface the ivar is conceptually a part of in the case of synthesized
142327a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar  /// ivars.
142427a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar  const ObjCInterfaceDecl *getContainingInterface() const;
1425ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
14262c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian  ObjCIvarDecl *getNextIvar() { return NextIvar; }
1427db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const ObjCIvarDecl *getNextIvar() const { return NextIvar; }
14282c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian  void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
142927a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar
1430980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  void setAccessControl(AccessControl ac) { DeclAccess = ac; }
1431f079570fcad0d0053e75ebae29c883ec4276e020Ted Kremenek
1432ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
1433f079570fcad0d0053e75ebae29c883ec4276e020Ted Kremenek
1434f079570fcad0d0053e75ebae29c883ec4276e020Ted Kremenek  AccessControl getCanonicalAccessControl() const {
1435f079570fcad0d0053e75ebae29c883ec4276e020Ted Kremenek    return DeclAccess == None ? Protected : AccessControl(DeclAccess);
1436f079570fcad0d0053e75ebae29c883ec4276e020Ted Kremenek  }
14371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1438ac0021ba802e193e0f9f8207768c7862c7603bc0Fariborz Jahanian  void setSynthesize(bool synth) { Synthesized = synth; }
1439ad51e74030a59a8aa4ef0ebca1d7a701602ef53bFariborz Jahanian  bool getSynthesize() const { return Synthesized; }
1440ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1441980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  // Implement isa/cast/dyncast/etc.
144280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
144380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ObjCIvar; }
1444980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroffprivate:
1445ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// NextIvar - Next Ivar in the list of ivars declared in class; class's
14462c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian  /// extensions and class's implementation
14472c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian  ObjCIvarDecl *NextIvar;
1448ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1449ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
1450ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek  unsigned DeclAccess : 3;
1451ad51e74030a59a8aa4ef0ebca1d7a701602ef53bFariborz Jahanian  unsigned Synthesized : 1;
1452980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
1453980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
14541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14550982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// \brief Represents a field declaration created by an \@defs(...).
145601e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenekclass ObjCAtDefsFieldDecl : public FieldDecl {
1457651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void anchor() override;
1458ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
1459ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                      SourceLocation IdLoc, IdentifierInfo *Id,
146001e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek                      QualType T, Expr *BW)
1461ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara    : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
14626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
1463ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith                BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
14641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
146501e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenekpublic:
146644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
1467ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                     SourceLocation StartLoc,
1468ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                     SourceLocation IdLoc, IdentifierInfo *Id,
1469ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                     QualType T, Expr *BW);
14701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14711e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
14721e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
147301e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek  // Implement isa/cast/dyncast/etc.
147480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
147580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
147601e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek};
1477980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
14780982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// \brief Represents an Objective-C protocol declaration.
14790982205bade2fb4fc984c27b2ab401e683963b10James Dennett///
14800982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// Objective-C protocols declare a pure abstract type (i.e., no instance
14810982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// variables are permitted).  Protocols originally drew inspiration from
14820982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// C++ pure virtual functions (a C++ feature with nice semantics and lousy
14830982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// syntax:-). Here is an example:
14840c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
14850982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// \code
148641c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \@protocol NSDraggingInfo <refproto1, refproto2>
14870c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - (NSWindow *)draggingDestinationWindow;
14880c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - (NSImage *)draggedImage;
148941c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \@end
14900982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// \endcode
14910c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
1492eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// This says that NSDraggingInfo requires two methods and requires everything
1493eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// that the two "referenced protocols" 'refproto1' and 'refproto2' require as
1494eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// well.
1495eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner///
14960982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// \code
14970982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// \@interface ImplementsNSDraggingInfo : NSObject \<NSDraggingInfo>
149841c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \@end
14990982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// \endcode
15000c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
1501a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
15020c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// protocols are in distinct namespaces. For example, Cocoa defines both
15031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// an NSObject protocol and class (which isn't allowed in Java). As a result,
15040c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// protocols are referenced using angle brackets as follows:
15050c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
15060982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// id \<NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
15070c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
15081d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregorclass ObjCProtocolDecl : public ObjCContainerDecl,
15091d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor                         public Redeclarable<ObjCProtocolDecl> {
1510651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void anchor() override;
151199ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
15125e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  struct DefinitionData {
15131d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor    // \brief The declaration that defines this protocol.
15141d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor    ObjCProtocolDecl *Definition;
15151d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor
1516ec1a58b201b3276966aaade8ac3ac4705aba96c2Douglas Gregor    /// \brief Referenced protocols
15175e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    ObjCProtocolList ReferencedProtocols;
15185e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  };
15196bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor
15206bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  /// \brief Contains a pointer to the data associated with this class,
15216bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  /// which will be NULL if this class has not yet been defined.
15226bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  ///
15236bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  /// The bit indicates when we don't need to check for out-of-date
15246bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  /// declarations. It will be set unless modules are enabled.
15256bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  llvm::PointerIntPair<DefinitionData *, 1, bool> Data;
15261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15275e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  DefinitionData &data() const {
15286bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    assert(Data.getPointer() && "Objective-C protocol has no definition!");
15296bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    return *Data.getPointer();
15305e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  }
15315e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor
15326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
1533b05d7b20171bbd2feb14b059f39332cbe1bf1014Argyrios Kyrtzidis                   SourceLocation nameLoc, SourceLocation atStartLoc,
1534c9d3c7edb513e9b8a6ab65b04133653e71d7a72bDouglas Gregor                   ObjCProtocolDecl *PrevDecl);
15351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15365e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  void allocateDefinitionData();
15371d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor
15381d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor  typedef Redeclarable<ObjCProtocolDecl> redeclarable_base;
15396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCProtocolDecl *getNextRedeclarationImpl() override {
15406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return getNextRedeclaration();
15411d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor  }
1542651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ObjCProtocolDecl *getPreviousDeclImpl() override {
1543ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor    return getPreviousDecl();
1544ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  }
1545651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ObjCProtocolDecl *getMostRecentDeclImpl() override {
1546ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor    return getMostRecentDecl();
1547ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  }
15486bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor
1549cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattnerpublic:
15501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
15511711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                                  IdentifierInfo *Id,
15521711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                                  SourceLocation nameLoc,
1553b05d7b20171bbd2feb14b059f39332cbe1bf1014Argyrios Kyrtzidis                                  SourceLocation atStartLoc,
1554c9d3c7edb513e9b8a6ab65b04133653e71d7a72bDouglas Gregor                                  ObjCProtocolDecl *PrevDecl);
1555cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner
15561e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID);
15576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
155818df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  const ObjCProtocolList &getReferencedProtocols() const {
15595e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    assert(hasDefinition() && "No definition available!");
15605e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    return data().ReferencedProtocols;
1561980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  }
156218df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  typedef ObjCProtocolList::iterator protocol_iterator;
1563651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<protocol_iterator> protocol_range;
1564651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  protocol_range protocols() const {
1566651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return protocol_range(protocol_begin(), protocol_end());
1567651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
15685e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  protocol_iterator protocol_begin() const {
15695e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    if (!hasDefinition())
15705e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor      return protocol_iterator();
15715e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor
15725e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    return data().ReferencedProtocols.begin();
15735e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  }
15745e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  protocol_iterator protocol_end() const {
15755e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    if (!hasDefinition())
15765e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor      return protocol_iterator();
15775e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor
15785e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    return data().ReferencedProtocols.end();
15795e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  }
158018df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
1581651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
1582651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1583651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  protocol_loc_range protocol_locs() const {
1584651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
1585651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
1586ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  protocol_loc_iterator protocol_loc_begin() const {
15875e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    if (!hasDefinition())
15885e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor      return protocol_loc_iterator();
15895e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor
15905e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    return data().ReferencedProtocols.loc_begin();
159118df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  }
1592ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  protocol_loc_iterator protocol_loc_end() const {
15935e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    if (!hasDefinition())
15945e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor      return protocol_loc_iterator();
15955e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor
15965e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    return data().ReferencedProtocols.loc_end();
15975e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  }
15985e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  unsigned protocol_size() const {
15995e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    if (!hasDefinition())
16005e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor      return 0;
16015e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor
16025e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    return data().ReferencedProtocols.size();
160318df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  }
16041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
160538af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  /// setProtocolList - Set the list of protocols that this interface
1606780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner  /// implements.
160738af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
160818df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor                       const SourceLocation *Locs, ASTContext &C) {
16096bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    assert(hasDefinition() && "Protocol is not defined");
16105e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    data().ReferencedProtocols.set(List, Num, Locs, C);
1611aebf0cba02c014ac8b19d615c654248e0e93779fFariborz Jahanian  }
16121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
161391b0b0cf6b537cbcbca0038c7032f87161a41d31Steve Naroff  ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName);
16141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
161594a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // Lookup a method. First, we search locally. If a method isn't
161694a5c3334bba3cc8cd1da85ba1118bc2c080add9Steve Naroff  // found, we search referenced protocols and class categories.
1617094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis  ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const;
1618094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis  ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
1619094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis    return lookupMethod(Sel, true/*isInstance*/);
1620094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis  }
1621094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis  ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
1622094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis    return lookupMethod(Sel, false/*isInstance*/);
1623094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis  }
1624b05d7b20171bbd2feb14b059f39332cbe1bf1014Argyrios Kyrtzidis
16255e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  /// \brief Determine whether this protocol has a definition.
16266bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  bool hasDefinition() const {
16276bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    // If the name of this protocol is out-of-date, bring it up-to-date, which
16286bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    // might bring in a definition.
16296bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    // Note: a null value indicates that we don't have a definition and that
16306bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    // modules are enabled.
16316bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    if (!Data.getOpaqueValue()) {
16326bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor      if (IdentifierInfo *II = getIdentifier()) {
16336bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor        if (II->isOutOfDate()) {
16346bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor          updateOutOfDate(*II);
16356bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor        }
16366bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor      }
16376bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    }
16386bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor
16396bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor    return Data.getPointer();
16406bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  }
16415e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor
16425e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  /// \brief Retrieve the definition of this protocol, if any.
16435e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  ObjCProtocolDecl *getDefinition() {
16446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return hasDefinition()? Data.getPointer()->Definition : nullptr;
16455e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  }
16465e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor
16475e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  /// \brief Retrieve the definition of this protocol, if any.
16485e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  const ObjCProtocolDecl *getDefinition() const {
16496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return hasDefinition()? Data.getPointer()->Definition : nullptr;
16505e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  }
16515e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor
16525e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  /// \brief Determine whether this particular declaration is also the
16535e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  /// definition.
16545e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  bool isThisDeclarationADefinition() const {
16555e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    return getDefinition() == this;
16565e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  }
16575e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor
16585e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  /// \brief Starts the definition of this Objective-C protocol.
16595e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  void startDefinition();
16605e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor
1661176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// Produce a name to be used for protocol's metadata. It comes either via
1662176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// objc_runtime_name attribute or protocol name.
1663176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  StringRef getObjCRuntimeNameAsString() const;
1664176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1665651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SourceRange getSourceRange() const override LLVM_READONLY {
1666ec1a58b201b3276966aaade8ac3ac4705aba96c2Douglas Gregor    if (isThisDeclarationADefinition())
1667ec1a58b201b3276966aaade8ac3ac4705aba96c2Douglas Gregor      return ObjCContainerDecl::getSourceRange();
1668ec1a58b201b3276966aaade8ac3ac4705aba96c2Douglas Gregor
1669ec1a58b201b3276966aaade8ac3ac4705aba96c2Douglas Gregor    return SourceRange(getAtStartLoc(), getLocation());
1670ec1a58b201b3276966aaade8ac3ac4705aba96c2Douglas Gregor  }
1671f785a7d611404cf4747287a2bbc59b4d0e6a5a8cDouglas Gregor
1672651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef redeclarable_base::redecl_range redecl_range;
1673a54fbf2499c7cc999e22abb9be484ce976ed9689Douglas Gregor  typedef redeclarable_base::redecl_iterator redecl_iterator;
1674ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::redecls_begin;
1675ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::redecls_end;
1676651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  using redeclarable_base::redecls;
1677ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::getPreviousDecl;
1678ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::getMostRecentDecl;
16797693b32af6863c63fcaf4de087760740ee675f71Rafael Espindola  using redeclarable_base::isFirstDecl;
1680f785a7d611404cf4747287a2bbc59b4d0e6a5a8cDouglas Gregor
16813fc73ee0c613715ebce78e30b4d050ea715a007dDouglas Gregor  /// Retrieves the canonical declaration of this Objective-C protocol.
1682651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ObjCProtocolDecl *getCanonicalDecl() override { return getFirstDecl(); }
1683bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola  const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); }
16843fc73ee0c613715ebce78e30b4d050ea715a007dDouglas Gregor
1685651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void collectPropertiesToImplement(PropertyMap &PM,
1686651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    PropertyDeclOrder &PO) const override;
1687651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1688651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
1689651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                          ProtocolPropertyMap &PM) const;
1690b36ea375e20f71df19c101fa2399b7ea3a607e04Anna Zaks
169180cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
169280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ObjCProtocol; }
1693b05d7b20171bbd2feb14b059f39332cbe1bf1014Argyrios Kyrtzidis
16945e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  friend class ASTReader;
1695b05d7b20171bbd2feb14b059f39332cbe1bf1014Argyrios Kyrtzidis  friend class ASTDeclReader;
1696b05d7b20171bbd2feb14b059f39332cbe1bf1014Argyrios Kyrtzidis  friend class ASTDeclWriter;
1697980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
16981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1699a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCCategoryDecl - Represents a category declaration. A category allows
17000c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// you to add methods to an existing class (without subclassing or modifying
17011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// the original class interface or implementation:-). Categories don't allow
17020c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// you to add instance data. The following example adds "myMethod" to all
17030c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// NSView's within a process:
17040c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
170541c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \@interface NSView (MyViewMethods)
17060c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - myMethod;
170741c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \@end
17080c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
170933ced0b8550f3e7169f326944731ee02e9338659Douglas Gregor/// Categories also allow you to split the implementation of a class across
17100c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// several files (a feature more naturally supported in C++).
17110c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
17120c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// Categories were originally inspired by dynamic languages such as Common
17131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// Lisp and Smalltalk.  More traditional class-based languages (C++, Java)
17140c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// don't support this level of dynamism, which is both powerful and dangerous.
17150c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
1716e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroffclass ObjCCategoryDecl : public ObjCContainerDecl {
1717651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void anchor() override;
171899ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
1719980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Interface belonging to this category
1720a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *ClassInterface;
17211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
172268c82cf61228102aba1194efef222fa1478af2a8Chris Lattner  /// referenced protocols in this category.
172318df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  ObjCProtocolList ReferencedProtocols;
17241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1725a8ff9f455d94d9609766cfd5186b6e21dc2102f1Chris Lattner  /// Next category belonging to this class.
1726a8ff9f455d94d9609766cfd5186b6e21dc2102f1Chris Lattner  /// FIXME: this should not be a singly-linked list.  Move storage elsewhere.
1727a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryDecl *NextClassCategory;
17281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17293db211b617c5073aa70eb25d37ed44ae0dca17c4Douglas Gregor  /// \brief The location of the category name in this declaration.
17303db211b617c5073aa70eb25d37ed44ae0dca17c4Douglas Gregor  SourceLocation CategoryNameLoc;
17311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1732af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian  /// class extension may have private ivars.
1733af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian  SourceLocation IvarLBraceLoc;
1734af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian  SourceLocation IvarRBraceLoc;
1735af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian
1736ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
17373db211b617c5073aa70eb25d37ed44ae0dca17c4Douglas Gregor                   SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
1738af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                   IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
1739af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                   SourceLocation IvarLBraceLoc=SourceLocation(),
1740af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                   SourceLocation IvarRBraceLoc=SourceLocation())
17411711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis    : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
17426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      ClassInterface(IDecl), NextClassCategory(nullptr),
1743af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian      CategoryNameLoc(CategoryNameLoc),
1744af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian      IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
1745a906135721c350435319347d2672bbb3bf494f91Chris Lattner  }
1746d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
174761f9d41036e30ff80130f99b31c0626e3ef057ccChris Lattnerpublic:
17481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1749d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
1750ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie                                  SourceLocation AtLoc,
17513db211b617c5073aa70eb25d37ed44ae0dca17c4Douglas Gregor                                  SourceLocation ClassNameLoc,
17523db211b617c5073aa70eb25d37ed44ae0dca17c4Douglas Gregor                                  SourceLocation CategoryNameLoc,
1753955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis                                  IdentifierInfo *Id,
1754af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                                  ObjCInterfaceDecl *IDecl,
1755af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                                  SourceLocation IvarLBraceLoc=SourceLocation(),
1756af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                                  SourceLocation IvarRBraceLoc=SourceLocation());
17571e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID);
17581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1759e0def7589a8afa8a6acef13476bb3f882c104b91Chris Lattner  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
1760e0def7589a8afa8a6acef13476bb3f882c104b91Chris Lattner  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
17618a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
17628a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  ObjCCategoryImplDecl *getImplementation() const;
17638a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  void setImplementation(ObjCCategoryImplDecl *ImplD);
17648a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
176538af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  /// setProtocolList - Set the list of protocols that this interface
1766f7b2c98c16dfb2261ea57d40a1d5bc4738e73175Chris Lattner  /// implements.
176738af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattner  void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
176818df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor                       const SourceLocation *Locs, ASTContext &C) {
176918df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor    ReferencedProtocols.set(List, Num, Locs, C);
1770780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner  }
17711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
177218df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  const ObjCProtocolList &getReferencedProtocols() const {
1773780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner    return ReferencedProtocols;
17748f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian  }
17751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
177618df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  typedef ObjCProtocolList::iterator protocol_iterator;
1777651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<protocol_iterator> protocol_range;
1778651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1779651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  protocol_range protocols() const {
1780651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return protocol_range(protocol_begin(), protocol_end());
1781651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
1782651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  protocol_iterator protocol_begin() const {
1783651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return ReferencedProtocols.begin();
1784651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
1785780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
178630833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff  unsigned protocol_size() const { return ReferencedProtocols.size(); }
178718df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
1788651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
1789651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1790651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  protocol_loc_range protocol_locs() const {
1791651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
1792651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
1793ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  protocol_loc_iterator protocol_loc_begin() const {
1794ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    return ReferencedProtocols.loc_begin();
179518df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  }
1796ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  protocol_loc_iterator protocol_loc_end() const {
1797ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    return ReferencedProtocols.loc_end();
179818df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  }
17991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1800a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
18013db211b617c5073aa70eb25d37ed44ae0dca17c4Douglas Gregor
1802d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// \brief Retrieve the pointer to the next stored category (or extension),
1803d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  /// which may be hidden.
1804d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  ObjCCategoryDecl *getNextClassCategoryRaw() const {
1805d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    return NextClassCategory;
1806d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  }
1807d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
18086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool IsClassExtension() const { return getIdentifier() == nullptr; }
1809ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
18100e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian  typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
1811651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
1812651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1813651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
18140e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian  ivar_iterator ivar_begin() const {
18150e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian    return ivar_iterator(decls_begin());
18160e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian  }
18170e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian  ivar_iterator ivar_end() const {
18180e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian    return ivar_iterator(decls_end());
18190e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian  }
18200e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian  unsigned ivar_size() const {
18210e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian    return std::distance(ivar_begin(), ivar_end());
18220e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian  }
18230e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian  bool ivar_empty() const {
18240e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian    return ivar_begin() == ivar_end();
18250e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian  }
18263db211b617c5073aa70eb25d37ed44ae0dca17c4Douglas Gregor
18273db211b617c5073aa70eb25d37ed44ae0dca17c4Douglas Gregor  SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
18283db211b617c5073aa70eb25d37ed44ae0dca17c4Douglas Gregor  void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; }
1829af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian
1830af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian  void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
1831af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian  SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
1832af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian  void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
1833af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian  SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
18343db211b617c5073aa70eb25d37ed44ae0dca17c4Douglas Gregor
183580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
183680cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ObjCCategory; }
1837955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis
1838955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis  friend class ASTDeclReader;
1839955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis  friend class ASTDeclWriter;
1840980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
18410c6b6243d3efd958c17943130e2a773653511edcSteve Naroff
1842aecae629269fae3bf484baf1d109e9a89d14eeadArgyrios Kyrtzidisclass ObjCImplDecl : public ObjCContainerDecl {
1843651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void anchor() override;
184499ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
18450d69b8cc8e90a9364771837cb42d7031b4cbb984Steve Naroff  /// Class interface for this class/category implementation
1846a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *ClassInterface;
18471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18483aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattnerprotected:
18491711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis  ObjCImplDecl(Kind DK, DeclContext *DC,
18501711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis               ObjCInterfaceDecl *classInterface,
18511711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis               SourceLocation nameLoc, SourceLocation atStartLoc)
18521711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis    : ObjCContainerDecl(DK, DC,
18536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                        classInterface? classInterface->getIdentifier()
18546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                      : nullptr,
18551711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                        nameLoc, atStartLoc),
1856aecae629269fae3bf484baf1d109e9a89d14eeadArgyrios Kyrtzidis      ClassInterface(classInterface) {}
18571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
185875c9cae5f85c72cbb1649e93849e16ede3f07522Chris Lattnerpublic:
1859e0def7589a8afa8a6acef13476bb3f882c104b91Chris Lattner  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
1860e0def7589a8afa8a6acef13476bb3f882c104b91Chris Lattner  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
18618a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  void setClassInterface(ObjCInterfaceDecl *IFace);
18622c2d43c557beca1b4ba4bd743f33978aecb46a97Douglas Gregor
18631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  void addInstanceMethod(ObjCMethodDecl *method) {
18642c2d43c557beca1b4ba4bd743f33978aecb46a97Douglas Gregor    // FIXME: Context should be set correctly before we get here.
1865653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor    method->setLexicalDeclContext(this);
18661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    addDecl(method);
1867e1e6c0d5c79c0ee7ed62fef47a19aa7ecef40db4Steve Naroff  }
18681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  void addClassMethod(ObjCMethodDecl *method) {
18692c2d43c557beca1b4ba4bd743f33978aecb46a97Douglas Gregor    // FIXME: Context should be set correctly before we get here.
1870653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor    method->setLexicalDeclContext(this);
18711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    addDecl(method);
187253df12d1ba68dbd071d067f8236c16fba815aad5Chris Lattner  }
18731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
187417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  void addPropertyImplementation(ObjCPropertyImplDecl *property);
18751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
187617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
187717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
1878653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor
1879653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor  // Iterator access to properties.
1880653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor  typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
1881651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyImplDecl>>
1882651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    propimpl_range;
1883651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1884651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  propimpl_range property_impls() const {
1885651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return propimpl_range(propimpl_begin(), propimpl_end());
1886651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
18871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  propimpl_iterator propimpl_begin() const {
188817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return propimpl_iterator(decls_begin());
1889559c0c4bbecc017aab0716d546c4fefbcc194687Fariborz Jahanian  }
18901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  propimpl_iterator propimpl_end() const {
189117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return propimpl_iterator(decls_end());
1892559c0c4bbecc017aab0716d546c4fefbcc194687Fariborz Jahanian  }
1893653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor
189480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
189580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
18969a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt    return K >= firstObjCImpl && K <= lastObjCImpl;
189780cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  }
18983aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner};
18991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ObjCCategoryImplDecl - An object of this class encapsulates a category
190141c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \@implementation declaration. If a category class has declaration of a
19021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// property, its implementation must be specified in the category's
190341c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \@implementation declaration. Example:
190441c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \@interface I \@end
190541c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \@interface I(CATEGORY)
190641c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth///    \@property int p1, d1;
190741c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \@end
190841c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \@implementation I(CATEGORY)
190941c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth///  \@dynamic p1,d1;
191041c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \@end
19113aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner///
19123aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner/// ObjCCategoryImplDecl
19133aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattnerclass ObjCCategoryImplDecl : public ObjCImplDecl {
1914651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void anchor() override;
191599ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
19163aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  // Category name
19173aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  IdentifierInfo *Id;
19183aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner
1919c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis  // Category name location
1920c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis  SourceLocation CategoryNameLoc;
1921c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis
19221711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis  ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id,
19231711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                       ObjCInterfaceDecl *classInterface,
1924c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis                       SourceLocation nameLoc, SourceLocation atStartLoc,
1925c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis                       SourceLocation CategoryNameLoc)
19261711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis    : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc),
1927c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis      Id(Id), CategoryNameLoc(CategoryNameLoc) {}
19283aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattnerpublic:
19293aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
19301711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                                      IdentifierInfo *Id,
19311711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                                      ObjCInterfaceDecl *classInterface,
19321711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                                      SourceLocation nameLoc,
1933c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis                                      SourceLocation atStartLoc,
1934c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis                                      SourceLocation CategoryNameLoc);
19351e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
19361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19370d69b8cc8e90a9364771837cb42d7031b4cbb984Steve Naroff  /// getIdentifier - Get the identifier that names the category
19383aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  /// interface associated with this implementation.
1939c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  /// FIXME: This is a bad API, we are hiding NamedDecl::getIdentifier()
1940c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  /// with a different meaning. For example:
1941ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
1942ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// returns the class interface name, whereas
1943ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
19440d69b8cc8e90a9364771837cb42d7031b4cbb984Steve Naroff  /// returns the category name.
19451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  IdentifierInfo *getIdentifier() const {
19461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return Id;
19473aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  }
194810b0e1fa3aabd8877dbbc0df1f2414e04afd5fddDouglas Gregor  void setIdentifier(IdentifierInfo *II) { Id = II; }
19491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19500d69b8cc8e90a9364771837cb42d7031b4cbb984Steve Naroff  ObjCCategoryDecl *getCategoryDecl() const;
195110b0e1fa3aabd8877dbbc0df1f2414e04afd5fddDouglas Gregor
1952c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis  SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
1953c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis
1954b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar  /// getName - Get the name of identifier for the class interface associated
1955b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar  /// with this implementation as a StringRef.
1956b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar  //
1957c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
1958c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // meaning.
1959c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  StringRef getName() const { return Id ? Id->getName() : StringRef(); }
1960b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar
19613aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  /// @brief Get the name of the class associated with this interface.
19627fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  //
1963b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar  // FIXME: Deprecated, move clients to getName().
19643aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  std::string getNameAsString() const {
1965b5217efa5be2fd6be48d207267c8bcda6bf9206cDaniel Dunbar    return getName();
19663aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris Lattner  }
19671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
196880cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
196980cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
1970c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis
1971c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis  friend class ASTDeclReader;
1972c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis  friend class ASTDeclWriter;
19738f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian};
19748f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian
1975f978059b82db8c0d849c5f992036210b5ca53200Benjamin Kramerraw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID);
1976900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer
1977a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ObjCImplementationDecl - Represents a class definition - this is where
19780c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// method definitions are specified. For example:
19790c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
198098abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// @code
198141c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \@implementation MyClass
19820c6b6243d3efd958c17943130e2a773653511edcSteve Naroff/// - (void)myMethod { /* do something */ }
198341c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \@end
198498abf4bd3526a00a0e5cf71a9462c181f97b1c81Fariborz Jahanian/// @endcode
19850c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
19866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// In a non-fragile runtime, instance variables can appear in the class
19876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// interface, class extensions (nameless categories), and in the implementation
19886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// itself, as well as being synthesized as backing storage for properties.
19890c6b6243d3efd958c17943130e2a773653511edcSteve Naroff///
19906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// In a fragile runtime, instance variables are specified in the class
19916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// interface, \em not in the implementation. Nevertheless (for legacy reasons),
19926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// we allow instance variables to be specified in the implementation. When
19936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// specified, they need to be \em identical to the interface.
19941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ObjCImplementationDecl : public ObjCImplDecl {
1995651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void anchor() override;
1996980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff  /// Implementation Class's super class.
1997a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *SuperClass;
1998634c5634817b9ad384a706fe87ab302985566bbaArgyrios Kyrtzidis  SourceLocation SuperLoc;
1999634c5634817b9ad384a706fe87ab302985566bbaArgyrios Kyrtzidis
200041c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// \@implementation may have private ivars.
2001af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian  SourceLocation IvarLBraceLoc;
2002af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian  SourceLocation IvarRBraceLoc;
2003af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian
2004e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  /// Support for ivar initialization.
20053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  /// \brief The arguments used to initialize the ivars
20063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  LazyCXXCtorInitializersPtr IvarInitializers;
2007e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  unsigned NumIvarInitializers;
2008f85e193739c953358c865005855253af4f68a497John McCall
2009b03527a9a395168762ad8e25e59a7a272dd74561John McCall  /// Do the ivars of this class require initialization other than
2010b03527a9a395168762ad8e25e59a7a272dd74561John McCall  /// zero-initialization?
2011b03527a9a395168762ad8e25e59a7a272dd74561John McCall  bool HasNonZeroConstructors : 1;
2012b03527a9a395168762ad8e25e59a7a272dd74561John McCall
2013b03527a9a395168762ad8e25e59a7a272dd74561John McCall  /// Do the ivars of this class require non-trivial destruction?
2014b03527a9a395168762ad8e25e59a7a272dd74561John McCall  bool HasDestructors : 1;
2015ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
20161711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis  ObjCImplementationDecl(DeclContext *DC,
2017a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                         ObjCInterfaceDecl *classInterface,
20181711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                         ObjCInterfaceDecl *superDecl,
2019af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                         SourceLocation nameLoc, SourceLocation atStartLoc,
2020634c5634817b9ad384a706fe87ab302985566bbaArgyrios Kyrtzidis                         SourceLocation superLoc = SourceLocation(),
2021af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                         SourceLocation IvarLBraceLoc=SourceLocation(),
2022af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                         SourceLocation IvarRBraceLoc=SourceLocation())
20231711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis    : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
2024634c5634817b9ad384a706fe87ab302985566bbaArgyrios Kyrtzidis       SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc),
2025af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian       IvarRBraceLoc(IvarRBraceLoc),
20266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines       IvarInitializers(nullptr), NumIvarInitializers(0),
2027b03527a9a395168762ad8e25e59a7a272dd74561John McCall       HasNonZeroConstructors(false), HasDestructors(false) {}
20281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic:
20291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
203075c9cae5f85c72cbb1649e93849e16ede3f07522Chris Lattner                                        ObjCInterfaceDecl *classInterface,
20311711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                                        ObjCInterfaceDecl *superDecl,
20321711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                                        SourceLocation nameLoc,
2033af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                                        SourceLocation atStartLoc,
2034634c5634817b9ad384a706fe87ab302985566bbaArgyrios Kyrtzidis                                     SourceLocation superLoc = SourceLocation(),
2035af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                                        SourceLocation IvarLBraceLoc=SourceLocation(),
2036af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                                        SourceLocation IvarRBraceLoc=SourceLocation());
2037ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
20381e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID);
20391e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
2040e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  /// init_iterator - Iterates through the ivar initializer list.
2041cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt  typedef CXXCtorInitializer **init_iterator;
2042ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
2043e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  /// init_const_iterator - Iterates through the ivar initializer list.
2044cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt  typedef CXXCtorInitializer * const * init_const_iterator;
2045ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
2046651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<init_iterator> init_range;
2047651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<init_const_iterator> init_const_range;
2048651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
2049651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  init_range inits() { return init_range(init_begin(), init_end()); }
2050651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  init_const_range inits() const {
2051651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return init_const_range(init_begin(), init_end());
2052651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
2053651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
2054e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  /// init_begin() - Retrieve an iterator to the first initializer.
20553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  init_iterator init_begin() {
20563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    const auto *ConstThis = this;
20573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    return const_cast<init_iterator>(ConstThis->init_begin());
20583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  }
2059e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  /// begin() - Retrieve an iterator to the first initializer.
20603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  init_const_iterator init_begin() const;
2061ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
2062e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  /// init_end() - Retrieve an iterator past the last initializer.
2063e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  init_iterator       init_end()       {
20643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    return init_begin() + NumIvarInitializers;
2065e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  }
2066e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  /// end() - Retrieve an iterator past the last initializer.
2067e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  init_const_iterator init_end() const {
20683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    return init_begin() + NumIvarInitializers;
2069e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  }
2070e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  /// getNumArgs - Number of ivars which must be initialized.
2071e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  unsigned getNumIvarInitializers() const {
2072e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian    return NumIvarInitializers;
2073e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  }
2074ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
2075e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  void setNumIvarInitializers(unsigned numNumIvarInitializers) {
2076e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian    NumIvarInitializers = numNumIvarInitializers;
2077e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  }
2078ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
2079e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian  void setIvarInitializers(ASTContext &C,
2080cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt                           CXXCtorInitializer ** initializers,
2081e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian                           unsigned numInitializers);
2082f85e193739c953358c865005855253af4f68a497John McCall
2083b03527a9a395168762ad8e25e59a7a272dd74561John McCall  /// Do any of the ivars of this class (not counting its base classes)
2084b03527a9a395168762ad8e25e59a7a272dd74561John McCall  /// require construction other than zero-initialization?
2085b03527a9a395168762ad8e25e59a7a272dd74561John McCall  bool hasNonZeroConstructors() const { return HasNonZeroConstructors; }
2086b03527a9a395168762ad8e25e59a7a272dd74561John McCall  void setHasNonZeroConstructors(bool val) { HasNonZeroConstructors = val; }
2087b03527a9a395168762ad8e25e59a7a272dd74561John McCall
2088b03527a9a395168762ad8e25e59a7a272dd74561John McCall  /// Do any of the ivars of this class (not counting its base classes)
2089b03527a9a395168762ad8e25e59a7a272dd74561John McCall  /// require non-trivial destruction?
2090b03527a9a395168762ad8e25e59a7a272dd74561John McCall  bool hasDestructors() const { return HasDestructors; }
2091b03527a9a395168762ad8e25e59a7a272dd74561John McCall  void setHasDestructors(bool val) { HasDestructors = val; }
2092ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
20934afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  /// getIdentifier - Get the identifier that names the class
20944afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  /// interface associated with this implementation.
20951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  IdentifierInfo *getIdentifier() const {
20961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return getClassInterface()->getIdentifier();
20974afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  }
20984afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor
2099d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar  /// getName - Get the name of identifier for the class interface associated
2100d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar  /// with this implementation as a StringRef.
2101d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar  //
2102c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
2103c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // meaning.
2104686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  StringRef getName() const {
2105d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar    assert(getIdentifier() && "Name is not a simple identifier");
2106d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar    return getIdentifier()->getName();
2107d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar  }
2108d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar
21094afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  /// @brief Get the name of the class associated with this interface.
21107fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  //
21117fe60650c1133ee74a3395cf1063690e274bb7acDaniel Dunbar  // FIXME: Move to StringRef API.
21124afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  std::string getNameAsString() const {
2113d0c10e20d5ba8c1a8a077db128c03eddc3158673Daniel Dunbar    return getName();
21144afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  }
2115176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
2116176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// Produce a name to be used for class's metadata. It comes either via
2117176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// class's objc_runtime_name attribute or class name.
2118176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  StringRef getObjCRuntimeNameAsString() const;
21194afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor
2120e0def7589a8afa8a6acef13476bb3f882c104b91Chris Lattner  const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
2121e0def7589a8afa8a6acef13476bb3f882c104b91Chris Lattner  ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
21222f729009067e6aff6198719ec9f8220d88cfea09Argyrios Kyrtzidis  SourceLocation getSuperClassLoc() const { return SuperLoc; }
21231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2124f3a7af901231535191d14cb524d58f22907ac4d2Chris Lattner  void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
21251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2126af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian  void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
2127af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian  SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
2128af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian  void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
2129af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian  SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
2130af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian
21318f36aba016c2d236a90f9ecf0a66904209202202Douglas Gregor  typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
2132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
2133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
2134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
21351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ivar_iterator ivar_begin() const {
21361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return ivar_iterator(decls_begin());
21378f36aba016c2d236a90f9ecf0a66904209202202Douglas Gregor  }
21381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ivar_iterator ivar_end() const {
213917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return ivar_iterator(decls_end());
21408f36aba016c2d236a90f9ecf0a66904209202202Douglas Gregor  }
21411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  unsigned ivar_size() const {
214217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return std::distance(ivar_begin(), ivar_end());
21438f36aba016c2d236a90f9ecf0a66904209202202Douglas Gregor  }
21441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool ivar_empty() const {
214517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    return ivar_begin() == ivar_end();
21468f36aba016c2d236a90f9ecf0a66904209202202Douglas Gregor  }
21471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
214880cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
214980cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ObjCImplementation; }
21509d50c0635fb213b2a1857e3f8488580f0dab2f98Argyrios Kyrtzidis
2151d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
21523397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
2153980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff};
2154243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian
2155f978059b82db8c0d849c5f992036210b5ca53200Benjamin Kramerraw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID);
2156900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer
21571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
215841c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// declared as \@compatibility_alias alias class.
21594afa39deaa245592977136d367251ee2c173dd8dDouglas Gregorclass ObjCCompatibleAliasDecl : public NamedDecl {
2160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void anchor() override;
2161243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  /// Class that this is an alias of.
2162a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl *AliasedClass;
21631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2164d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
2165e8043c39176e7f253fbd92982b077eca6bf2fd59Steve Naroff                          ObjCInterfaceDecl* aliasedClass)
21664afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {}
2167f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattnerpublic:
2168d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC,
21690ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner                                         SourceLocation L, IdentifierInfo *Id,
2170f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner                                         ObjCInterfaceDecl* aliasedClass);
2171f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner
21721e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C,
21731e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                     unsigned ID);
21741e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
2175f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner  const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
2176f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner  ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
217730833f8d77c08f8f16371776fde85a9fde3d9b6eSteve Naroff  void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
21781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
217980cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
218080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
21811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2182243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian};
21831de1e74541c25c1a7b721f1c3991ea34c8403420Fariborz Jahanian
21840982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// \brief Represents one property declaration in an Objective-C interface.
21850982205bade2fb4fc984c27b2ab401e683963b10James Dennett///
21861de1e74541c25c1a7b721f1c3991ea34c8403420Fariborz Jahanian/// For example:
21870982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// \code{.mm}
218841c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \@property (assign, readwrite) int MyProperty;
21890982205bade2fb4fc984c27b2ab401e683963b10James Dennett/// \endcode
21904afa39deaa245592977136d367251ee2c173dd8dDouglas Gregorclass ObjCPropertyDecl : public NamedDecl {
2191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void anchor() override;
219282a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanianpublic:
2193a5674258f5e6f74f1c0ed3ece4d64fbb1b9afb11Chris Lattner  enum PropertyAttributeKind {
21941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    OBJC_PR_noattr    = 0x00,
21951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    OBJC_PR_readonly  = 0x01,
2196a5674258f5e6f74f1c0ed3ece4d64fbb1b9afb11Chris Lattner    OBJC_PR_getter    = 0x02,
21971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    OBJC_PR_assign    = 0x04,
21981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    OBJC_PR_readwrite = 0x08,
2199a5674258f5e6f74f1c0ed3ece4d64fbb1b9afb11Chris Lattner    OBJC_PR_retain    = 0x10,
22001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    OBJC_PR_copy      = 0x20,
2201a5674258f5e6f74f1c0ed3ece4d64fbb1b9afb11Chris Lattner    OBJC_PR_nonatomic = 0x40,
220245937ae10a0f70f74508165aab4f2b63e18ea747Fariborz Jahanian    OBJC_PR_setter    = 0x80,
2203f85e193739c953358c865005855253af4f68a497John McCall    OBJC_PR_atomic    = 0x100,
2204f85e193739c953358c865005855253af4f68a497John McCall    OBJC_PR_weak      = 0x200,
2205f85e193739c953358c865005855253af4f68a497John McCall    OBJC_PR_strong    = 0x400,
22069f3480bab8fcb6547978f8ad9e2b8f468e3658eeArgyrios Kyrtzidis    OBJC_PR_unsafe_unretained = 0x800
22079f3480bab8fcb6547978f8ad9e2b8f468e3658eeArgyrios Kyrtzidis    // Adding a property should change NumPropertyAttrsBits
22089f3480bab8fcb6547978f8ad9e2b8f468e3658eeArgyrios Kyrtzidis  };
22090a68dc7f04be1542ce249ff4adb169453698ad91Argyrios Kyrtzidis
22109f3480bab8fcb6547978f8ad9e2b8f468e3658eeArgyrios Kyrtzidis  enum {
22110a68dc7f04be1542ce249ff4adb169453698ad91Argyrios Kyrtzidis    /// \brief Number of bits fitting all the property attributes.
22129f3480bab8fcb6547978f8ad9e2b8f468e3658eeArgyrios Kyrtzidis    NumPropertyAttrsBits = 12
2213a5674258f5e6f74f1c0ed3ece4d64fbb1b9afb11Chris Lattner  };
2214af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
22153a02b44e3948f7762dbfba94b7961281ca29d022Fariborz Jahanian  enum SetterKind { Assign, Retain, Copy, Weak };
221646b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian  enum PropertyControl { None, Required, Optional };
221782a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanianprivate:
221841c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  SourceLocation AtLoc;   // location of \@property
221977bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian  SourceLocation LParenLoc; // location of '(' starting attribute list or null.
222083a230c83a54190366138c1a4f4310ef838b88fcJohn McCall  TypeSourceInfo *DeclType;
22219f3480bab8fcb6547978f8ad9e2b8f468e3658eeArgyrios Kyrtzidis  unsigned PropertyAttributes : NumPropertyAttrsBits;
22229f3480bab8fcb6547978f8ad9e2b8f468e3658eeArgyrios Kyrtzidis  unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
222341c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  // \@required/\@optional
222446b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian  unsigned PropertyImplementation : 2;
22251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22265251e130a23d997f7c0dfdc250cdc41f179e5bedFariborz Jahanian  Selector GetterName;    // getter name of NULL if no getter
22275251e130a23d997f7c0dfdc250cdc41f179e5bedFariborz Jahanian  Selector SetterName;    // setter name of NULL if no setter
22281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
222933de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian  ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
223033de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian  ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
2231af3e72285238369c2ea4ebd40a1c9a87bd3eabb7Fariborz Jahanian  ObjCIvarDecl *PropertyIvarDecl;   // Synthesize ivar for this property
223233de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian
22331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
223477bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian                   SourceLocation AtLocation,  SourceLocation LParenLocation,
223577bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian                   TypeSourceInfo *T)
223677bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian    : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
223777bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian      LParenLoc(LParenLocation), DeclType(T),
2238ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie      PropertyAttributes(OBJC_PR_noattr),
223980aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian      PropertyAttributesAsWritten(OBJC_PR_noattr),
224080aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian      PropertyImplementation(None),
22411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      GetterName(Selector()),
224233de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian      SetterName(Selector()),
22436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      GetterMethodDecl(nullptr), SetterMethodDecl(nullptr),
22446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      PropertyIvarDecl(nullptr) {}
22456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
2246f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattnerpublic:
22471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
22481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                  SourceLocation L,
2249d0502407c1b41b2ace326f355d7b7a6876246223Fariborz Jahanian                                  IdentifierInfo *Id, SourceLocation AtLocation,
225077bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian                                  SourceLocation LParenLocation,
225183a230c83a54190366138c1a4f4310ef838b88fcJohn McCall                                  TypeSourceInfo *T,
225246b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian                                  PropertyControl propControl = None);
22531e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
22541e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
22551e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
2256d0502407c1b41b2ace326f355d7b7a6876246223Fariborz Jahanian  SourceLocation getAtLoc() const { return AtLoc; }
2257d0502407c1b41b2ace326f355d7b7a6876246223Fariborz Jahanian  void setAtLoc(SourceLocation L) { AtLoc = L; }
225877bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian
225977bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian  SourceLocation getLParenLoc() const { return LParenLoc; }
226077bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
2261ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
226283a230c83a54190366138c1a4f4310ef838b88fcJohn McCall  TypeSourceInfo *getTypeSourceInfo() const { return DeclType; }
226383a230c83a54190366138c1a4f4310ef838b88fcJohn McCall  QualType getType() const { return DeclType->getType(); }
226483a230c83a54190366138c1a4f4310ef838b88fcJohn McCall  void setType(TypeSourceInfo *T) { DeclType = T; }
226570e5a14c6076d63833c62d1d6d628c26309897c1Douglas Gregor
2266a5674258f5e6f74f1c0ed3ece4d64fbb1b9afb11Chris Lattner  PropertyAttributeKind getPropertyAttributes() const {
2267f4af5154571e0c5eadb19df10e65464766ef6683Chris Lattner    return PropertyAttributeKind(PropertyAttributes);
2268f4af5154571e0c5eadb19df10e65464766ef6683Chris Lattner  }
22691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  void setPropertyAttributes(PropertyAttributeKind PRVal) {
2270a5674258f5e6f74f1c0ed3ece4d64fbb1b9afb11Chris Lattner    PropertyAttributes |= PRVal;
227182a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian  }
2272394d33f1f602f7681032a659dff5bb09061ee510Daniel Dunbar
227380aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian  PropertyAttributeKind getPropertyAttributesAsWritten() const {
227480aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian    return PropertyAttributeKind(PropertyAttributesAsWritten);
227580aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian  }
22760a68dc7f04be1542ce249ff4adb169453698ad91Argyrios Kyrtzidis
22770a68dc7f04be1542ce249ff4adb169453698ad91Argyrios Kyrtzidis  bool hasWrittenStorageAttribute() const {
22780a68dc7f04be1542ce249ff4adb169453698ad91Argyrios Kyrtzidis    return PropertyAttributesAsWritten & (OBJC_PR_assign | OBJC_PR_copy |
22790a68dc7f04be1542ce249ff4adb169453698ad91Argyrios Kyrtzidis        OBJC_PR_unsafe_unretained | OBJC_PR_retain | OBJC_PR_strong |
22800a68dc7f04be1542ce249ff4adb169453698ad91Argyrios Kyrtzidis        OBJC_PR_weak);
22810a68dc7f04be1542ce249ff4adb169453698ad91Argyrios Kyrtzidis  }
2282ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
228380aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian  void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
228480aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian    PropertyAttributesAsWritten = PRVal;
228580aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian  }
2286ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
2287c4a77906c259cba58c147d8468c406a430ecdcbbDmitri Gribenko void makeitReadWriteAttribute() {
22888cf0bb3c2a798ce3acacaac2d3178648cd4c65c6Fariborz Jahanian    PropertyAttributes &= ~OBJC_PR_readonly;
22898cf0bb3c2a798ce3acacaac2d3178648cd4c65c6Fariborz Jahanian    PropertyAttributes |= OBJC_PR_readwrite;
22901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump }
22918cf0bb3c2a798ce3acacaac2d3178648cd4c65c6Fariborz Jahanian
2292af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  // Helper methods for accessing attributes.
2293af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
2294f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru  /// isReadOnly - Return true iff the property has a setter.
2295394d33f1f602f7681032a659dff5bb09061ee510Daniel Dunbar  bool isReadOnly() const {
2296394d33f1f602f7681032a659dff5bb09061ee510Daniel Dunbar    return (PropertyAttributes & OBJC_PR_readonly);
2297394d33f1f602f7681032a659dff5bb09061ee510Daniel Dunbar  }
2298af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
2299265941bc308d65cc270d5c4de5806f37ce405606John McCall  /// isAtomic - Return true if the property is atomic.
2300265941bc308d65cc270d5c4de5806f37ce405606John McCall  bool isAtomic() const {
2301265941bc308d65cc270d5c4de5806f37ce405606John McCall    return (PropertyAttributes & OBJC_PR_atomic);
2302265941bc308d65cc270d5c4de5806f37ce405606John McCall  }
2303265941bc308d65cc270d5c4de5806f37ce405606John McCall
2304265941bc308d65cc270d5c4de5806f37ce405606John McCall  /// isRetaining - Return true if the property retains its value.
2305265941bc308d65cc270d5c4de5806f37ce405606John McCall  bool isRetaining() const {
2306265941bc308d65cc270d5c4de5806f37ce405606John McCall    return (PropertyAttributes &
2307265941bc308d65cc270d5c4de5806f37ce405606John McCall            (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy));
2308265941bc308d65cc270d5c4de5806f37ce405606John McCall  }
2309265941bc308d65cc270d5c4de5806f37ce405606John McCall
2310af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  /// getSetterKind - Return the method used for doing assignment in
2311af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  /// the property setter. This is only valid if the property has been
2312af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  /// defined to have a setter.
2313af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  SetterKind getSetterKind() const {
23146dc6f008994472cf4da321855e8c51c39720f3edJohn McCall    if (PropertyAttributes & OBJC_PR_strong)
23156dc6f008994472cf4da321855e8c51c39720f3edJohn McCall      return getType()->isBlockPointerType() ? Copy : Retain;
23166dc6f008994472cf4da321855e8c51c39720f3edJohn McCall    if (PropertyAttributes & OBJC_PR_retain)
2317af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar      return Retain;
2318af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar    if (PropertyAttributes & OBJC_PR_copy)
2319af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar      return Copy;
23203a02b44e3948f7762dbfba94b7961281ca29d022Fariborz Jahanian    if (PropertyAttributes & OBJC_PR_weak)
23213a02b44e3948f7762dbfba94b7961281ca29d022Fariborz Jahanian      return Weak;
2322af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar    return Assign;
2323af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  }
2324af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
23255251e130a23d997f7c0dfdc250cdc41f179e5bedFariborz Jahanian  Selector getGetterName() const { return GetterName; }
23265251e130a23d997f7c0dfdc250cdc41f179e5bedFariborz Jahanian  void setGetterName(Selector Sel) { GetterName = Sel; }
23271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23285251e130a23d997f7c0dfdc250cdc41f179e5bedFariborz Jahanian  Selector getSetterName() const { return SetterName; }
23295251e130a23d997f7c0dfdc250cdc41f179e5bedFariborz Jahanian  void setSetterName(Selector Sel) { SetterName = Sel; }
23301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
233133de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian  ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
233233de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian  void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
233333de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian
233433de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian  ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
233533de3f0333ca0b5274291b8d76c86758c0484691Fariborz Jahanian  void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
23361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
233741c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  // Related to \@optional/\@required declared in \@protocol
233846b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian  void setPropertyImplementation(PropertyControl pc) {
233946b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian    PropertyImplementation = pc;
234046b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian  }
234146b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian  PropertyControl getPropertyImplementation() const {
234246b55e56d029aec699fc2701e43d70264da9ecd8Fariborz Jahanian    return PropertyControl(PropertyImplementation);
23431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
23441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2345af3e72285238369c2ea4ebd40a1c9a87bd3eabb7Fariborz Jahanian  void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
2346af3e72285238369c2ea4ebd40a1c9a87bd3eabb7Fariborz Jahanian    PropertyIvarDecl = Ivar;
2347af3e72285238369c2ea4ebd40a1c9a87bd3eabb7Fariborz Jahanian  }
2348af3e72285238369c2ea4ebd40a1c9a87bd3eabb7Fariborz Jahanian  ObjCIvarDecl *getPropertyIvarDecl() const {
2349af3e72285238369c2ea4ebd40a1c9a87bd3eabb7Fariborz Jahanian    return PropertyIvarDecl;
2350af3e72285238369c2ea4ebd40a1c9a87bd3eabb7Fariborz Jahanian  }
23511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2352651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SourceRange getSourceRange() const override LLVM_READONLY {
2353e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor    return SourceRange(AtLoc, getLocation());
2354e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor  }
2355ad0ce53c8219456938405b84c5d13341a47e3d94Anna Zaks
2356ad0ce53c8219456938405b84c5d13341a47e3d94Anna Zaks  /// Get the default name of the synthesized ivar.
2357ad0ce53c8219456938405b84c5d13341a47e3d94Anna Zaks  IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const;
2358e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor
23599f550ff05d496e6b9480e5619a21d9da0c9e27c1Ted Kremenek  /// Lookup a property by name in the specified DeclContext.
2360de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek  static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
2361176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                            const IdentifierInfo *propertyID);
23629f550ff05d496e6b9480e5619a21d9da0c9e27c1Ted Kremenek
236380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
236480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ObjCProperty; }
236582a5fe3d1cf204b672cdab24d72275b6ad2c3527Fariborz Jahanian};
2366980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
23671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ObjCPropertyImplDecl - Represents implementation declaration of a property
236861d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian/// in a class or category implementation block. For example:
236941c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth/// \@synthesize prop1 = ivar1;
237061d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian///
23714afa39deaa245592977136d367251ee2c173dd8dDouglas Gregorclass ObjCPropertyImplDecl : public Decl {
237261d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanianpublic:
23739f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbar  enum Kind {
23749f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbar    Synthesize,
23759f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbar    Dynamic
237661d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian  };
237761d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanianprivate:
237841c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  SourceLocation AtLoc;   // location of \@synthesize or \@dynamic
2379ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
238041c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// \brief For \@synthesize, the location of the ivar, if it was written in
2381a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor  /// the source code.
2382a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor  ///
2383a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor  /// \code
238441c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// \@synthesize int a = b
2385a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor  /// \endcode
2386a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor  SourceLocation IvarLoc;
2387ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
238861d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian  /// Property declaration being implemented
238961d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian  ObjCPropertyDecl *PropertyDecl;
2390be57c3a3fef0776fca57ad88b2db263f37b074c4Ted Kremenek
239141c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// Null for \@dynamic. Required for \@synthesize.
239261d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian  ObjCIvarDecl *PropertyIvarDecl;
2393ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
239441c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// Null for \@dynamic. Non-null if property must be copy-constructed in
239541c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// getter.
239617cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian  Expr *GetterCXXConstructor;
2397ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
239841c2bcff88a23a046ee8d71451bc03717a4248f6Chandler Carruth  /// Null for \@dynamic. Non-null if property has assignment operator to call
239917cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian  /// in Setter synthesis.
240017cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian  Expr *SetterCXXAssignment;
2401be57c3a3fef0776fca57ad88b2db263f37b074c4Ted Kremenek
2402d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
24031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       ObjCPropertyDecl *property,
24041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       Kind PK,
2405a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor                       ObjCIvarDecl *ivarDecl,
2406a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor                       SourceLocation ivarLoc)
24071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
2408ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie      IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl),
24096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      GetterCXXConstructor(nullptr), SetterCXXAssignment(nullptr) {
24109f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbar    assert (PK == Dynamic || PropertyIvarDecl);
24119f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbar  }
24121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24139f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbarpublic:
2414d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC,
24151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                      SourceLocation atLoc, SourceLocation L,
24161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                      ObjCPropertyDecl *property,
24171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                      Kind PK,
2418a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor                                      ObjCIvarDecl *ivarDecl,
2419a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor                                      SourceLocation ivarLoc);
242061d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian
24211e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2422651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
2423651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SourceRange getSourceRange() const override LLVM_READONLY;
2424ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
2425aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
24268818c4fb69cb2a4eec94b217a90f94f9e075296eDouglas Gregor  void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
2427d40910b581b09c937a8c1fdcde9b8ec724398fb9Steve Naroff
2428be57c3a3fef0776fca57ad88b2db263f37b074c4Ted Kremenek  ObjCPropertyDecl *getPropertyDecl() const {
2429be57c3a3fef0776fca57ad88b2db263f37b074c4Ted Kremenek    return PropertyDecl;
2430be57c3a3fef0776fca57ad88b2db263f37b074c4Ted Kremenek  }
24318818c4fb69cb2a4eec94b217a90f94f9e075296eDouglas Gregor  void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; }
24328818c4fb69cb2a4eec94b217a90f94f9e075296eDouglas Gregor
24339f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbar  Kind getPropertyImplementation() const {
24349f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbar    return PropertyIvarDecl ? Synthesize : Dynamic;
2435be57c3a3fef0776fca57ad88b2db263f37b074c4Ted Kremenek  }
24361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2437af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCIvarDecl *getPropertyIvarDecl() const {
2438be57c3a3fef0776fca57ad88b2db263f37b074c4Ted Kremenek    return PropertyIvarDecl;
2439be57c3a3fef0776fca57ad88b2db263f37b074c4Ted Kremenek  }
2440a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor  SourceLocation getPropertyIvarDeclLoc() const { return IvarLoc; }
2441ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
2442a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor  void setPropertyIvarDecl(ObjCIvarDecl *Ivar,
2443ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie                           SourceLocation IvarLoc) {
2444ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    PropertyIvarDecl = Ivar;
2445a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor    this->IvarLoc = IvarLoc;
2446a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor  }
2447ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
2448135bf8ee69e2ae2daea4f713381995028c41e264Argyrios Kyrtzidis  /// \brief For \@synthesize, returns true if an ivar name was explicitly
2449135bf8ee69e2ae2daea4f713381995028c41e264Argyrios Kyrtzidis  /// specified.
2450135bf8ee69e2ae2daea4f713381995028c41e264Argyrios Kyrtzidis  ///
2451135bf8ee69e2ae2daea4f713381995028c41e264Argyrios Kyrtzidis  /// \code
2452135bf8ee69e2ae2daea4f713381995028c41e264Argyrios Kyrtzidis  /// \@synthesize int a = b; // true
2453135bf8ee69e2ae2daea4f713381995028c41e264Argyrios Kyrtzidis  /// \@synthesize int a; // false
2454135bf8ee69e2ae2daea4f713381995028c41e264Argyrios Kyrtzidis  /// \endcode
2455135bf8ee69e2ae2daea4f713381995028c41e264Argyrios Kyrtzidis  bool isIvarNameSpecified() const {
2456135bf8ee69e2ae2daea4f713381995028c41e264Argyrios Kyrtzidis    return IvarLoc.isValid() && IvarLoc != getLocation();
2457135bf8ee69e2ae2daea4f713381995028c41e264Argyrios Kyrtzidis  }
2458135bf8ee69e2ae2daea4f713381995028c41e264Argyrios Kyrtzidis
245917cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian  Expr *getGetterCXXConstructor() const {
246017cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian    return GetterCXXConstructor;
246117cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian  }
246217cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian  void setGetterCXXConstructor(Expr *getterCXXConstructor) {
246317cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian    GetterCXXConstructor = getterCXXConstructor;
246417cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian  }
24658818c4fb69cb2a4eec94b217a90f94f9e075296eDouglas Gregor
246617cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian  Expr *getSetterCXXAssignment() const {
246717cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian    return SetterCXXAssignment;
246817cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian  }
246917cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian  void setSetterCXXAssignment(Expr *setterCXXAssignment) {
247017cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian    SetterCXXAssignment = setterCXXAssignment;
247117cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian  }
2472ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
247380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
247480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
2475ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
2476a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor  friend class ASTDeclReader;
247761d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian};
247861d46159af2a740207de8dc024211d531ae290d9Fariborz Jahanian
2479d329724745b49f894b768d47275b7c2713106e89Douglas Gregortemplate<bool (*Filter)(ObjCCategoryDecl *)>
2480d329724745b49f894b768d47275b7c2713106e89Douglas Gregorvoid
2481d329724745b49f894b768d47275b7c2713106e89Douglas GregorObjCInterfaceDecl::filtered_category_iterator<Filter>::
2482d329724745b49f894b768d47275b7c2713106e89Douglas GregorfindAcceptableCategory() {
2483d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  while (Current && !Filter(Current))
2484d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    Current = Current->getNextClassCategoryRaw();
2485d329724745b49f894b768d47275b7c2713106e89Douglas Gregor}
2486d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
2487d329724745b49f894b768d47275b7c2713106e89Douglas Gregortemplate<bool (*Filter)(ObjCCategoryDecl *)>
2488d329724745b49f894b768d47275b7c2713106e89Douglas Gregorinline ObjCInterfaceDecl::filtered_category_iterator<Filter> &
2489d329724745b49f894b768d47275b7c2713106e89Douglas GregorObjCInterfaceDecl::filtered_category_iterator<Filter>::operator++() {
2490d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  Current = Current->getNextClassCategoryRaw();
2491d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  findAcceptableCategory();
2492d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  return *this;
2493d329724745b49f894b768d47275b7c2713106e89Douglas Gregor}
2494d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
2495d329724745b49f894b768d47275b7c2713106e89Douglas Gregorinline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) {
2496d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  return !Cat->isHidden();
2497d329724745b49f894b768d47275b7c2713106e89Douglas Gregor}
2498d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
2499d329724745b49f894b768d47275b7c2713106e89Douglas Gregorinline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) {
2500d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  return Cat->IsClassExtension() && !Cat->isHidden();
2501d329724745b49f894b768d47275b7c2713106e89Douglas Gregor}
2502d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
2503d329724745b49f894b768d47275b7c2713106e89Douglas Gregorinline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) {
2504d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  return Cat->IsClassExtension();
2505d329724745b49f894b768d47275b7c2713106e89Douglas Gregor}
2506d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
2507980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff}  // end namespace clang
2508980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff#endif
2509