11e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner//===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===//
21e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner//
31e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner//                     The LLVM Compiler Infrastructure
41e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner//
51e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner// This file is distributed under the University of Illinois Open Source
61e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner// License. See LICENSE.TXT for details.
71e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner//
81e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner//===----------------------------------------------------------------------===//
91e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner//
101e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner// This file implements the Objective-C related Decl classes.
111e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner//
121e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner//===----------------------------------------------------------------------===//
131e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner
141e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner#include "clang/AST/DeclObjC.h"
151e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner#include "clang/AST/ASTContext.h"
16e6b8d68a927368b06ac06cc9ac9e7f60aa966d5fArgyrios Kyrtzidis#include "clang/AST/ASTMutationListener.h"
172fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "clang/AST/Attr.h"
182fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "clang/AST/Stmt.h"
190de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff#include "llvm/ADT/STLExtras.h"
20ad0ce53c8219456938405b84c5d13341a47e3d94Anna Zaks#include "llvm/ADT/SmallString.h"
211e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattnerusing namespace clang;
221e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner
236c4ae5de0c356777446f823b573821fb95560d91Chris Lattner//===----------------------------------------------------------------------===//
2411e1e1af2641affb378080a4f3d1a30da1cad082Chris Lattner// ObjCListBase
2511e1e1af2641affb378080a4f3d1a30da1cad082Chris Lattner//===----------------------------------------------------------------------===//
2611e1e1af2641affb378080a4f3d1a30da1cad082Chris Lattner
2738af2deb27cdfa1a95bde96e30dab15dce53fcefChris Lattnervoid ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  List = nullptr;
2911e1e1af2641affb378080a4f3d1a30da1cad082Chris Lattner  if (Elts == 0) return;  // Setting to an empty list is a noop.
301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
324ee413ba81c8030c195a9166847928054ed01ca4Chris Lattner  List = new (Ctx) void*[Elts];
3311e1e1af2641affb378080a4f3d1a30da1cad082Chris Lattner  NumElts = Elts;
3411e1e1af2641affb378080a4f3d1a30da1cad082Chris Lattner  memcpy(List, InList, sizeof(void*)*Elts);
3511e1e1af2641affb378080a4f3d1a30da1cad082Chris Lattner}
3611e1e1af2641affb378080a4f3d1a30da1cad082Chris Lattner
3718df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregorvoid ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts,
3818df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor                           const SourceLocation *Locs, ASTContext &Ctx) {
3918df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  if (Elts == 0)
4018df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor    return;
4118df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor
4218df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  Locations = new (Ctx) SourceLocation[Elts];
4318df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  memcpy(Locations, Locs, sizeof(SourceLocation) * Elts);
4418df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  set(InList, Elts, Ctx);
4518df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor}
4618df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor
4711e1e1af2641affb378080a4f3d1a30da1cad082Chris Lattner//===----------------------------------------------------------------------===//
48ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner// ObjCInterfaceDecl
49ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
50ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
5199ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid ObjCContainerDecl::anchor() { }
5299ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
53496b5a894c5ec5425de53909f5aac3fb4771a2ecFariborz Jahanian/// getIvarDecl - This method looks up an ivar in this ContextDecl.
54496b5a894c5ec5425de53909f5aac3fb4771a2ecFariborz Jahanian///
55496b5a894c5ec5425de53909f5aac3fb4771a2ecFariborz JahanianObjCIvarDecl *
5617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios KyrtzidisObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
573bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie  lookup_const_result R = lookup(Id);
583bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie  for (lookup_const_iterator Ivar = R.begin(), IvarEnd = R.end();
593bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie       Ivar != IvarEnd; ++Ivar) {
60496b5a894c5ec5425de53909f5aac3fb4771a2ecFariborz Jahanian    if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
61496b5a894c5ec5425de53909f5aac3fb4771a2ecFariborz Jahanian      return ivar;
62496b5a894c5ec5425de53909f5aac3fb4771a2ecFariborz Jahanian  }
636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
64496b5a894c5ec5425de53909f5aac3fb4771a2ecFariborz Jahanian}
65496b5a894c5ec5425de53909f5aac3fb4771a2ecFariborz Jahanian
66467c0b165072689ef87fe8d9cd47a5b63485bcdcArgyrios Kyrtzidis// Get the local instance/class method declared in this interface.
676ab3524f72a6e64aa04973fa9433b5559abb3525Douglas GregorObjCMethodDecl *
6804593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios KyrtzidisObjCContainerDecl::getMethod(Selector Sel, bool isInstance,
6904593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis                             bool AllowHidden) const {
700f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor  // If this context is a hidden protocol definition, don't find any
710f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor  // methods there.
720f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor  if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
730f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor    if (const ObjCProtocolDecl *Def = Proto->getDefinition())
7404593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis      if (Def->isHidden() && !AllowHidden)
756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        return nullptr;
760f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor  }
770f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor
780de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff  // Since instance & class methods can have the same name, the loop below
790de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff  // ensures we get the correct method.
800de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff  //
810de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff  // @interface Whatever
820de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff  // - (int) class_method;
830de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff  // + (float) class_method;
840de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff  // @end
850de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff  //
863bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie  lookup_const_result R = lookup(Sel);
873bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie  for (lookup_const_iterator Meth = R.begin(), MethEnd = R.end();
883bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie       Meth != MethEnd; ++Meth) {
890de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff    ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
90467c0b165072689ef87fe8d9cd47a5b63485bcdcArgyrios Kyrtzidis    if (MD && MD->isInstanceMethod() == isInstance)
910de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff      return MD;
920de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff  }
936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
94ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner}
95ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
965bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian/// HasUserDeclaredSetterMethod - This routine returns 'true' if a user declared setter
975bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian/// method was found in the class, its protocols, its super classes or categories.
985bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian/// It also returns 'true' if one of its categories has declared a 'readwrite' property.
995bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian/// This is because, user must provide a setter method for the category's 'readwrite'
1005bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian/// property.
1015bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanianbool
1025bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz JahanianObjCContainerDecl::HasUserDeclaredSetterMethod(const ObjCPropertyDecl *Property) const {
1035bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian  Selector Sel = Property->getSetterName();
1045bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian  lookup_const_result R = lookup(Sel);
1055bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian  for (lookup_const_iterator Meth = R.begin(), MethEnd = R.end();
1065bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian       Meth != MethEnd; ++Meth) {
1075bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian    ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
1085bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian    if (MD && MD->isInstanceMethod() && !MD->isImplicit())
1095bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian      return true;
1105bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian  }
1115bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian
1125bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian  if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(this)) {
1135bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian    // Also look into categories, including class extensions, looking
1145bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian    // for a user declared instance method.
115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *Cat : ID->visible_categories()) {
1165bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian      if (ObjCMethodDecl *MD = Cat->getInstanceMethod(Sel))
1175bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian        if (!MD->isImplicit())
1185bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian          return true;
1195bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian      if (Cat->IsClassExtension())
1205bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian        continue;
1215bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian      // Also search through the categories looking for a 'readwrite' declaration
1225bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian      // of this property. If one found, presumably a setter will be provided
1235bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian      // (properties declared in categories will not get auto-synthesized).
124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      for (const auto *P : Cat->properties())
1255bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian        if (P->getIdentifier() == Property->getIdentifier()) {
1265bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian          if (P->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readwrite)
1275bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian            return true;
1285bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian          break;
1295bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian        }
1305bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian    }
1315bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian
1325bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian    // Also look into protocols, for a user declared instance method.
133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *Proto : ID->all_referenced_protocols())
1345bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian      if (Proto->HasUserDeclaredSetterMethod(Property))
1355bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian        return true;
136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1375bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian    // And in its super class.
1385bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian    ObjCInterfaceDecl *OSC = ID->getSuperClass();
1395bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian    while (OSC) {
1405bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian      if (OSC->HasUserDeclaredSetterMethod(Property))
1415bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian        return true;
1425bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian      OSC = OSC->getSuperClass();
1435bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian    }
1445bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian  }
1455bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian  if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(this))
146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *PI : PD->protocols())
147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (PI->HasUserDeclaredSetterMethod(Property))
1485bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian        return true;
1495bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian  return false;
1505bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian}
1515bdaef55d486f20346fe16f3d41324694d3ff0d5Fariborz Jahanian
1529f550ff05d496e6b9480e5619a21d9da0c9e27c1Ted KremenekObjCPropertyDecl *
153de09d0c9694f01a99870a8825266d44a29ebb325Ted KremenekObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
1549f550ff05d496e6b9480e5619a21d9da0c9e27c1Ted Kremenek                                   IdentifierInfo *propertyID) {
1550f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor  // If this context is a hidden protocol definition, don't find any
1560f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor  // property.
1570f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor  if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(DC)) {
1580f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor    if (const ObjCProtocolDecl *Def = Proto->getDefinition())
1590f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor      if (Def->isHidden())
1606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        return nullptr;
1610f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor  }
1629f550ff05d496e6b9480e5619a21d9da0c9e27c1Ted Kremenek
1633bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie  DeclContext::lookup_const_result R = DC->lookup(propertyID);
1643bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie  for (DeclContext::lookup_const_iterator I = R.begin(), E = R.end(); I != E;
1653bc93e3124ad5e7191c4a12dc981c8ee53578193David Blaikie       ++I)
1669f550ff05d496e6b9480e5619a21d9da0c9e27c1Ted Kremenek    if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(*I))
1679f550ff05d496e6b9480e5619a21d9da0c9e27c1Ted Kremenek      return PD;
1689f550ff05d496e6b9480e5619a21d9da0c9e27c1Ted Kremenek
1696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
1709f550ff05d496e6b9480e5619a21d9da0c9e27c1Ted Kremenek}
1719f550ff05d496e6b9480e5619a21d9da0c9e27c1Ted Kremenek
172ad0ce53c8219456938405b84c5d13341a47e3d94Anna ZaksIdentifierInfo *
173ad0ce53c8219456938405b84c5d13341a47e3d94Anna ZaksObjCPropertyDecl::getDefaultSynthIvarName(ASTContext &Ctx) const {
174ad0ce53c8219456938405b84c5d13341a47e3d94Anna Zaks  SmallString<128> ivarName;
175ad0ce53c8219456938405b84c5d13341a47e3d94Anna Zaks  {
176ad0ce53c8219456938405b84c5d13341a47e3d94Anna Zaks    llvm::raw_svector_ostream os(ivarName);
177ad0ce53c8219456938405b84c5d13341a47e3d94Anna Zaks    os << '_' << getIdentifier()->getName();
178ad0ce53c8219456938405b84c5d13341a47e3d94Anna Zaks  }
179ad0ce53c8219456938405b84c5d13341a47e3d94Anna Zaks  return &Ctx.Idents.get(ivarName.str());
180ad0ce53c8219456938405b84c5d13341a47e3d94Anna Zaks}
181ad0ce53c8219456938405b84c5d13341a47e3d94Anna Zaks
182ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner/// FindPropertyDeclaration - Finds declaration of the property given its name
183ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner/// in 'PropertyId' and returns it. It returns 0, if not found.
184ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris LattnerObjCPropertyDecl *
18517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios KyrtzidisObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
1860f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor  // Don't find properties within hidden protocol definitions.
1870f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor  if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
1880f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor    if (const ObjCProtocolDecl *Def = Proto->getDefinition())
1890f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor      if (Def->isHidden())
1906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        return nullptr;
1910f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor  }
1921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
193de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek  if (ObjCPropertyDecl *PD =
194de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek        ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
195de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek    return PD;
196de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek
197de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek  switch (getKind()) {
198de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek    default:
199de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek      break;
200de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek    case Decl::ObjCProtocol: {
201de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek      const ObjCProtocolDecl *PID = cast<ObjCProtocolDecl>(this);
202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      for (const auto *I : PID->protocols())
203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
20425760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian          return P;
205de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek      break;
206ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    }
207de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek    case Decl::ObjCInterface: {
208de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek      const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(this);
209d329724745b49f894b768d47275b7c2713106e89Douglas Gregor      // Look through categories (but not extensions).
210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      for (const auto *Cat : OID->visible_categories()) {
211de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek        if (!Cat->IsClassExtension())
212de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek          if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(PropertyId))
213de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek            return P;
214d329724745b49f894b768d47275b7c2713106e89Douglas Gregor      }
215de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek
216de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek      // Look through protocols.
217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      for (const auto *I : OID->all_referenced_protocols())
218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
219de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek          return P;
220de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek
221de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek      // Finally, check the super class.
222de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek      if (const ObjCInterfaceDecl *superClass = OID->getSuperClass())
223de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek        return superClass->FindPropertyDeclaration(PropertyId);
224de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek      break;
225ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    }
226de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek    case Decl::ObjCCategory: {
227de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek      const ObjCCategoryDecl *OCD = cast<ObjCCategoryDecl>(this);
228de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek      // Look through protocols.
229de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek      if (!OCD->IsClassExtension())
230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        for (const auto *I : OCD->protocols())
231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            return P;
233de09d0c9694f01a99870a8825266d44a29ebb325Ted Kremenek      break;
234ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    }
235ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner  }
2366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
237ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner}
238ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
23999ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid ObjCInterfaceDecl::anchor() { }
24099ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
241a6f14e1a7ee3a9343a838297c73ca87fddb9ed4aFariborz Jahanian/// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
242a6f14e1a7ee3a9343a838297c73ca87fddb9ed4aFariborz Jahanian/// with name 'PropertyId' in the primary class; including those in protocols
24337cafb077ad5b170acae77e566638603011ef4c0Ted Kremenek/// (direct or indirect) used by the primary class.
244a6f14e1a7ee3a9343a838297c73ca87fddb9ed4aFariborz Jahanian///
245a6f14e1a7ee3a9343a838297c73ca87fddb9ed4aFariborz JahanianObjCPropertyDecl *
24637cafb077ad5b170acae77e566638603011ef4c0Ted KremenekObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
247a6f14e1a7ee3a9343a838297c73ca87fddb9ed4aFariborz Jahanian                                            IdentifierInfo *PropertyId) const {
2482e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  // FIXME: Should make sure no callers ever do this.
2492e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  if (!hasDefinition())
2506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
2516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
2522e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  if (data().ExternallyCompleted)
25326ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor    LoadExternalDefinition();
25426ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor
25537cafb077ad5b170acae77e566638603011ef4c0Ted Kremenek  if (ObjCPropertyDecl *PD =
25637cafb077ad5b170acae77e566638603011ef4c0Ted Kremenek      ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
25737cafb077ad5b170acae77e566638603011ef4c0Ted Kremenek    return PD;
25837cafb077ad5b170acae77e566638603011ef4c0Ted Kremenek
259a6f14e1a7ee3a9343a838297c73ca87fddb9ed4aFariborz Jahanian  // Look through protocols.
260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *I : all_referenced_protocols())
261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
262a6f14e1a7ee3a9343a838297c73ca87fddb9ed4aFariborz Jahanian      return P;
26337cafb077ad5b170acae77e566638603011ef4c0Ted Kremenek
2646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
265a6f14e1a7ee3a9343a838297c73ca87fddb9ed4aFariborz Jahanian}
266a6f14e1a7ee3a9343a838297c73ca87fddb9ed4aFariborz Jahanian
267cfaed8d399a34e79fbab9f70eb4ea1bbeb81a02bFariborz Jahanianvoid ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM,
268cfaed8d399a34e79fbab9f70eb4ea1bbeb81a02bFariborz Jahanian                                                     PropertyDeclOrder &PO) const {
269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *Prop : properties()) {
270b36ea375e20f71df19c101fa2399b7ea3a607e04Anna Zaks    PM[Prop->getIdentifier()] = Prop;
271cfaed8d399a34e79fbab9f70eb4ea1bbeb81a02bFariborz Jahanian    PO.push_back(Prop);
272b36ea375e20f71df19c101fa2399b7ea3a607e04Anna Zaks  }
273651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *PI : all_referenced_protocols())
274651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PI->collectPropertiesToImplement(PM, PO);
275e63aedd0cb064fc106636ad856cc0e645e6374ceAnna Zaks  // Note, the properties declared only in class extensions are still copied
276e63aedd0cb064fc106636ad856cc0e645e6374ceAnna Zaks  // into the main @interface's property list, and therefore we don't
277e63aedd0cb064fc106636ad856cc0e645e6374ceAnna Zaks  // explicitly, have to search class extension properties.
278b36ea375e20f71df19c101fa2399b7ea3a607e04Anna Zaks}
279b36ea375e20f71df19c101fa2399b7ea3a607e04Anna Zaks
2802fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramerbool ObjCInterfaceDecl::isArcWeakrefUnavailable() const {
2812fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer  const ObjCInterfaceDecl *Class = this;
2822fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer  while (Class) {
2832fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer    if (Class->hasAttr<ArcWeakrefUnavailableAttr>())
2842fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer      return true;
2852fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer    Class = Class->getSuperClass();
2862fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer  }
2872fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer  return false;
2882fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer}
2892fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer
2902fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramerconst ObjCInterfaceDecl *ObjCInterfaceDecl::isObjCRequiresPropertyDefs() const {
2912fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer  const ObjCInterfaceDecl *Class = this;
2922fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer  while (Class) {
2932fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer    if (Class->hasAttr<ObjCRequiresPropertyDefsAttr>())
2942fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer      return Class;
2952fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer    Class = Class->getSuperClass();
2962fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer  }
2976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
2982fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer}
2992fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer
300339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanianvoid ObjCInterfaceDecl::mergeClassExtensionProtocolList(
301339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian                              ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
302339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian                              ASTContext &C)
303339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian{
3042e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  if (data().ExternallyCompleted)
30526ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor    LoadExternalDefinition();
30626ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor
3072e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  if (data().AllReferencedProtocols.empty() &&
3082e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor      data().ReferencedProtocols.empty()) {
3092e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    data().AllReferencedProtocols.set(ExtList, ExtNum, C);
310339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian    return;
311339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian  }
31253b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek
313339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian  // Check for duplicate protocol in class's protocol list.
31453b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek  // This is O(n*m). But it is extremely rare and number of protocols in
315339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian  // class or its extension are very few.
3165f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
317339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian  for (unsigned i = 0; i < ExtNum; i++) {
318339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian    bool protocolExists = false;
319339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian    ObjCProtocolDecl *ProtoInExtension = ExtList[i];
320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (auto *Proto : all_referenced_protocols()) {
321339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian      if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
322339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian        protocolExists = true;
323339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian        break;
324339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian      }
325339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian    }
326339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian    // Do we want to warn on a protocol in extension class which
327339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian    // already exist in the class? Probably not.
32853b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek    if (!protocolExists)
329339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian      ProtocolRefs.push_back(ProtoInExtension);
330339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian  }
33153b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek
332339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian  if (ProtocolRefs.empty())
333339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian    return;
33453b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek
335b106fc635b1523952332131785b700453a936e49Fariborz Jahanian  // Merge ProtocolRefs into class's protocol list;
336651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *P : all_referenced_protocols()) {
337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ProtocolRefs.push_back(P);
33818df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor  }
33953b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek
3402e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C);
341339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian}
342339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian
343651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesconst ObjCInterfaceDecl *
344651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesObjCInterfaceDecl::findInterfaceWithDesignatedInitializers() const {
345651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const ObjCInterfaceDecl *IFace = this;
346651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  while (IFace) {
347651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (IFace->hasDesignatedInitializers())
348651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return IFace;
349651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (!IFace->inheritsDesignatedInitializers())
350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      break;
351651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    IFace = IFace->getSuperClass();
352651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
3536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic bool isIntroducingInitializers(const ObjCInterfaceDecl *D) {
357651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *MD : D->instance_methods()) {
358651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
359651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return true;
360651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
361651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *Ext : D->visible_extensions()) {
362651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *MD : Ext->instance_methods()) {
363651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
364651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        return true;
365651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
3676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (const auto *ImplD = D->getImplementation()) {
3686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    for (const auto *MD : ImplD->instance_methods()) {
3696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
3706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        return true;
3716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    }
3726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
373651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return false;
374651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
375651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
376651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesbool ObjCInterfaceDecl::inheritsDesignatedInitializers() const {
377651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  switch (data().InheritedDesignatedInitializers) {
378651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case DefinitionData::IDI_Inherited:
379651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return true;
380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case DefinitionData::IDI_NotInherited:
381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return false;
382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  case DefinitionData::IDI_Unknown: {
383651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // If the class introduced initializers we conservatively assume that we
384651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // don't know if any of them is a designated initializer to avoid possible
385651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // misleading warnings.
386651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (isIntroducingInitializers(this)) {
387651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      data().InheritedDesignatedInitializers = DefinitionData::IDI_NotInherited;
388651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    } else {
3896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (auto SuperD = getSuperClass()) {
3906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        data().InheritedDesignatedInitializers =
3916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          SuperD->declaresOrInheritsDesignatedInitializers() ?
3926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines            DefinitionData::IDI_Inherited :
3936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines            DefinitionData::IDI_NotInherited;
3946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      } else {
3956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        data().InheritedDesignatedInitializers =
3966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          DefinitionData::IDI_NotInherited;
3976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      }
398651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
3996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(data().InheritedDesignatedInitializers
4006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines             != DefinitionData::IDI_Unknown);
4016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return data().InheritedDesignatedInitializers ==
4026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        DefinitionData::IDI_Inherited;
403651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
404651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
406651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  llvm_unreachable("unexpected InheritedDesignatedInitializers value");
407651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
408651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
409651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid ObjCInterfaceDecl::getDesignatedInitializers(
410651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const {
411651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Check for a complete definition and recover if not so.
412651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!isThisDeclarationADefinition())
413651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return;
414651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (data().ExternallyCompleted)
415651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    LoadExternalDefinition();
416651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
417651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
418651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!IFace)
419651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return;
420651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
421651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *MD : IFace->instance_methods())
422651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (MD->isThisDeclarationADesignatedInitializer())
423651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Methods.push_back(MD);
424651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *Ext : IFace->visible_extensions()) {
425651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *MD : Ext->instance_methods())
426651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (MD->isThisDeclarationADesignatedInitializer())
427651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        Methods.push_back(MD);
428651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
429651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
430651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
431651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesbool ObjCInterfaceDecl::isDesignatedInitializer(Selector Sel,
432651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                      const ObjCMethodDecl **InitMethod) const {
433651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Check for a complete definition and recover if not so.
434651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!isThisDeclarationADefinition())
435651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return false;
436651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (data().ExternallyCompleted)
437651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    LoadExternalDefinition();
438651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
439651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
440651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!IFace)
441651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return false;
442651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
443651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (const ObjCMethodDecl *MD = IFace->getInstanceMethod(Sel)) {
444651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (MD->isThisDeclarationADesignatedInitializer()) {
445651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (InitMethod)
446651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        *InitMethod = MD;
447651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return true;
448651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
449651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
450651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *Ext : IFace->visible_extensions()) {
451651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (const ObjCMethodDecl *MD = Ext->getInstanceMethod(Sel)) {
452651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (MD->isThisDeclarationADesignatedInitializer()) {
453651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (InitMethod)
454651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          *InitMethod = MD;
455651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        return true;
456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      }
457651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
459651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return false;
460651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4622e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregorvoid ObjCInterfaceDecl::allocateDefinitionData() {
4632e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  assert(!hasDefinition() && "ObjC class already has a definition");
4646bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  Data.setPointer(new (getASTContext()) DefinitionData());
4656bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  Data.getPointer()->Definition = this;
4668d2dbbf9ddfd9d762a341d83f83d840ff68ce03dDouglas Gregor
4678d2dbbf9ddfd9d762a341d83f83d840ff68ce03dDouglas Gregor  // Make the type point at the definition, now that we have one.
4688d2dbbf9ddfd9d762a341d83f83d840ff68ce03dDouglas Gregor  if (TypeForDecl)
4698d2dbbf9ddfd9d762a341d83f83d840ff68ce03dDouglas Gregor    cast<ObjCInterfaceType>(TypeForDecl)->Decl = this;
4700af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor}
4710af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor
4720af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregorvoid ObjCInterfaceDecl::startDefinition() {
4730af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor  allocateDefinitionData();
4740af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor
47553df7a1d34f21d8f2309311d1067d463e9064c60Douglas Gregor  // Update all of the declarations with a pointer to the definition.
476651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto RD : redecls()) {
477651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (RD != this)
47826fec63b14565e9e2d8c9935b276b99be950444aDouglas Gregor      RD->Data = Data;
47953df7a1d34f21d8f2309311d1067d463e9064c60Douglas Gregor  }
480ad834d534e9a5db3d3baa09593775f83ceaff1f2Argyrios Kyrtzidis}
481ad834d534e9a5db3d3baa09593775f83ceaff1f2Argyrios Kyrtzidis
48217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios KyrtzidisObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
48317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis                                              ObjCInterfaceDecl *&clsDeclared) {
4842e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  // FIXME: Should make sure no callers ever do this.
4852e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  if (!hasDefinition())
4866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
4872e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
4882e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  if (data().ExternallyCompleted)
4897c81c2a5915878e4aa6908a097290fd47fb3a154Argyrios Kyrtzidis    LoadExternalDefinition();
4907c81c2a5915878e4aa6908a097290fd47fb3a154Argyrios Kyrtzidis
491ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner  ObjCInterfaceDecl* ClassDecl = this;
4926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  while (ClassDecl != nullptr) {
49317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
494496b5a894c5ec5425de53909f5aac3fb4771a2ecFariborz Jahanian      clsDeclared = ClassDecl;
495496b5a894c5ec5425de53909f5aac3fb4771a2ecFariborz Jahanian      return I;
496ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    }
497d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
498651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *Ext : ClassDecl->visible_extensions()) {
499d329724745b49f894b768d47275b7c2713106e89Douglas Gregor      if (ObjCIvarDecl *I = Ext->getIvarDecl(ID)) {
5000e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian        clsDeclared = ClassDecl;
5010e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian        return I;
5020e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian      }
50380aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian    }
5040e5ad255729ee86b8ed57e659029008984517cdeFariborz Jahanian
505ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    ClassDecl = ClassDecl->getSuperClass();
506ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner  }
5076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
508ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner}
509ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
510cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian/// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
511cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian/// class whose name is passed as argument. If it is not one of the super classes
512cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian/// the it returns NULL.
513cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz JahanianObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
514cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian                                        const IdentifierInfo*ICName) {
5152e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  // FIXME: Should make sure no callers ever do this.
5162e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  if (!hasDefinition())
5176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
5182e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
5192e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  if (data().ExternallyCompleted)
5207c81c2a5915878e4aa6908a097290fd47fb3a154Argyrios Kyrtzidis    LoadExternalDefinition();
5217c81c2a5915878e4aa6908a097290fd47fb3a154Argyrios Kyrtzidis
522cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian  ObjCInterfaceDecl* ClassDecl = this;
5236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  while (ClassDecl != nullptr) {
524cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian    if (ClassDecl->getIdentifier() == ICName)
525cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian      return ClassDecl;
526cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian    ClassDecl = ClassDecl->getSuperClass();
527cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian  }
5286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
529cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian}
530cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian
53107b1bbe648a21b8cdbc073fb6a409422c49921bbFariborz JahanianObjCProtocolDecl *
53207b1bbe648a21b8cdbc073fb6a409422c49921bbFariborz JahanianObjCInterfaceDecl::lookupNestedProtocol(IdentifierInfo *Name) {
533651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *P : all_referenced_protocols())
534651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (P->lookupProtocolNamed(Name))
535651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return P;
53607b1bbe648a21b8cdbc073fb6a409422c49921bbFariborz Jahanian  ObjCInterfaceDecl *SuperClass = getSuperClass();
5376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return SuperClass ? SuperClass->lookupNestedProtocol(Name) : nullptr;
53807b1bbe648a21b8cdbc073fb6a409422c49921bbFariborz Jahanian}
53907b1bbe648a21b8cdbc073fb6a409422c49921bbFariborz Jahanian
540aa5420c1e36ab8e0e4bb87239d8b73a3a8ce75dbArgyrios Kyrtzidis/// lookupMethod - This method returns an instance/class method by looking in
541ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner/// the class, its categories, and its super classes (using a linear search).
542f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian/// When argument category "C" is specified, any implicit method found
543f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian/// in this category is ignored.
544bf393be8a0b8b573ceb23ed19ac953832a2a69e4Fariborz JahanianObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
545651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                bool isInstance,
546651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                bool shallowCategoryLookup,
547651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                bool followSuper,
548651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                const ObjCCategoryDecl *C) const
549651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{
5502e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  // FIXME: Should make sure no callers ever do this.
5512e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  if (!hasDefinition())
5526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
5532e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
554aa5420c1e36ab8e0e4bb87239d8b73a3a8ce75dbArgyrios Kyrtzidis  const ObjCInterfaceDecl* ClassDecl = this;
5556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCMethodDecl *MethodDecl = nullptr;
5561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5572e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  if (data().ExternallyCompleted)
55826ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor    LoadExternalDefinition();
55926ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor
560651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  while (ClassDecl) {
561aa5420c1e36ab8e0e4bb87239d8b73a3a8ce75dbArgyrios Kyrtzidis    if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
562ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner      return MethodDecl;
5631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
564ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    // Didn't find one yet - look through protocols.
565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *I : ClassDecl->protocols())
566651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
567ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner        return MethodDecl;
568bf393be8a0b8b573ceb23ed19ac953832a2a69e4Fariborz Jahanian
569bf393be8a0b8b573ceb23ed19ac953832a2a69e4Fariborz Jahanian    // Didn't find one yet - now look through categories.
570651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *Cat : ClassDecl->visible_categories()) {
571f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian      if ((MethodDecl = Cat->getMethod(Sel, isInstance)))
572651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (C != Cat || !MethodDecl->isImplicit())
573c775b1a0702621e297d00452a897381c8bf10f3fFariborz Jahanian          return MethodDecl;
574c775b1a0702621e297d00452a897381c8bf10f3fFariborz Jahanian
575f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian      if (!shallowCategoryLookup) {
576f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian        // Didn't find one yet - look through protocols.
577f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian        const ObjCList<ObjCProtocolDecl> &Protocols =
578f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian        Cat->getReferencedProtocols();
579f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian        for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
580f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian             E = Protocols.end(); I != E; ++I)
581f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian          if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
582651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            if (C != Cat || !MethodDecl->isImplicit())
583c775b1a0702621e297d00452a897381c8bf10f3fFariborz Jahanian              return MethodDecl;
584bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian      }
585f3f0f357f8d6b4511b6d605cc8a39ae3787fef6dFariborz Jahanian    }
586651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
587651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (!followSuper)
5886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return nullptr;
589651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
590651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // Get the super class (if any).
591ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    ClassDecl = ClassDecl->getSuperClass();
592ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner  }
5936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
594ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner}
595ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
596e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks// Will search "local" class/category implementations for a method decl.
597e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks// If failed, then we search in class's root for an instance method.
598e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks// Returns 0 if no method is found.
59974b2756bc1f1f5f7c189996fe7e4cd3efef70263Fariborz JahanianObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
60074b2756bc1f1f5f7c189996fe7e4cd3efef70263Fariborz Jahanian                                   const Selector &Sel,
601ca93ee707d9570b74d24c7d55defe18dac38bcc0Anna Zaks                                   bool Instance) const {
6022e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  // FIXME: Should make sure no callers ever do this.
6032e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  if (!hasDefinition())
6046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
6052e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
6062e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  if (data().ExternallyCompleted)
6077c81c2a5915878e4aa6908a097290fd47fb3a154Argyrios Kyrtzidis    LoadExternalDefinition();
6087c81c2a5915878e4aa6908a097290fd47fb3a154Argyrios Kyrtzidis
6096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCMethodDecl *Method = nullptr;
610d789d3d985e28c9404e62157af46dcb7331920e0Steve Naroff  if (ObjCImplementationDecl *ImpDecl = getImplementation())
61174b2756bc1f1f5f7c189996fe7e4cd3efef70263Fariborz Jahanian    Method = Instance ? ImpDecl->getInstanceMethod(Sel)
61274b2756bc1f1f5f7c189996fe7e4cd3efef70263Fariborz Jahanian                      : ImpDecl->getClassMethod(Sel);
613e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks
614e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks  // Look through local category implementations associated with the class.
615e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks  if (!Method)
616e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks    Method = Instance ? getCategoryInstanceMethod(Sel)
617e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks                      : getCategoryClassMethod(Sel);
618e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks
619e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks  // Before we give up, check if the selector is an instance method.
620e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks  // But only in the root. This matches gcc's behavior and what the
621e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks  // runtime expects.
622e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks  if (!Instance && !Method && !getSuperClass()) {
623e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks    Method = lookupInstanceMethod(Sel);
624e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks    // Look through local category implementations associated
625e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks    // with the root class.
626e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks    if (!Method)
627e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks      Method = lookupPrivateMethod(Sel, true);
628e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks  }
629e61354b274ec5aa6acf3d15271896ce7596bb123Anna Zaks
630d789d3d985e28c9404e62157af46dcb7331920e0Steve Naroff  if (!Method && getSuperClass())
63174b2756bc1f1f5f7c189996fe7e4cd3efef70263Fariborz Jahanian    return getSuperClass()->lookupPrivateMethod(Sel, Instance);
632d789d3d985e28c9404e62157af46dcb7331920e0Steve Naroff  return Method;
633d789d3d985e28c9404e62157af46dcb7331920e0Steve Naroff}
634ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
635ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
636ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner// ObjCMethodDecl
6376c4ae5de0c356777446f823b573821fb95560d91Chris Lattner//===----------------------------------------------------------------------===//
6386c4ae5de0c356777446f823b573821fb95560d91Chris Lattner
639651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesObjCMethodDecl *ObjCMethodDecl::Create(
640651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
641651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
642651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    DeclContext *contextDecl, bool isInstance, bool isVariadic,
643651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    bool isPropertyAccessor, bool isImplicitlyDeclared, bool isDefined,
644651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ImplementationControl impControl, bool HasRelatedResultType) {
645651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return new (C, contextDecl) ObjCMethodDecl(
646651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      beginLoc, endLoc, SelInfo, T, ReturnTInfo, contextDecl, isInstance,
647651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      isVariadic, isPropertyAccessor, isImplicitlyDeclared, isDefined,
648651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      impControl, HasRelatedResultType);
6490e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner}
6500e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner
6511e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas GregorObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
652651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(),
6536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                    Selector(), QualType(), nullptr, nullptr);
654651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
655651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
656651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesbool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const {
657651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return getMethodFamily() == OMF_init &&
658651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      hasAttr<ObjCDesignatedInitializerAttr>();
659651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
660651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
661651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesbool ObjCMethodDecl::isDesignatedInitializerForTheInterface(
662651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    const ObjCMethodDecl **InitMethod) const {
663651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (getMethodFamily() != OMF_init)
664651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return false;
665651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const DeclContext *DC = getDeclContext();
666651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (isa<ObjCProtocolDecl>(DC))
667651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return false;
668651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (const ObjCInterfaceDecl *ID = getClassInterface())
669651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return ID->isDesignatedInitializer(getSelector(), InitMethod);
670651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return false;
6711e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor}
6721e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
6735456b0fe40714a78cd0ba7c1a5b7dc34eda385afDouglas GregorStmt *ObjCMethodDecl::getBody() const {
6745456b0fe40714a78cd0ba7c1a5b7dc34eda385afDouglas Gregor  return Body.get(getASTContext().getExternalSource());
6755456b0fe40714a78cd0ba7c1a5b7dc34eda385afDouglas Gregor}
6765456b0fe40714a78cd0ba7c1a5b7dc34eda385afDouglas Gregor
6773a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidisvoid ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) {
6783a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis  assert(PrevMethod);
6793a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis  getASTContext().setObjCMethodRedeclaration(PrevMethod, this);
6803a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis  IsRedeclaration = true;
68172b2625aa67c8213acaf4bf6209b67859d60e2cfArgyrios Kyrtzidis  PrevMethod->HasRedeclaration = true;
6823a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis}
6833a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis
684491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidisvoid ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
685491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                                         ArrayRef<ParmVarDecl*> Params,
686491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                                         ArrayRef<SourceLocation> SelLocs) {
6876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ParamsAndSelLocs = nullptr;
688491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  NumParams = Params.size();
689491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  if (Params.empty() && SelLocs.empty())
690491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    return;
691491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
692491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  unsigned Size = sizeof(ParmVarDecl *) * NumParams +
693491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                  sizeof(SourceLocation) * SelLocs.size();
694491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  ParamsAndSelLocs = C.Allocate(Size);
695491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  std::copy(Params.begin(), Params.end(), getParams());
696491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
697491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis}
698491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
699491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidisvoid ObjCMethodDecl::getSelectorLocs(
700491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                               SmallVectorImpl<SourceLocation> &SelLocs) const {
701491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
702491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    SelLocs.push_back(getSelectorLoc(i));
703491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis}
704491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
705491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidisvoid ObjCMethodDecl::setMethodParams(ASTContext &C,
706491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                                     ArrayRef<ParmVarDecl*> Params,
707491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                                     ArrayRef<SourceLocation> SelLocs) {
708491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  assert((!SelLocs.empty() || isImplicit()) &&
709491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis         "No selector locs for non-implicit method");
710491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  if (isImplicit())
7115543169296beeb183b9c9392debc774fcf493eebDmitri Gribenko    return setParamsAndSelLocs(C, Params, llvm::None);
712491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
713a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios Kyrtzidis  SelLocsKind = hasStandardSelectorLocs(getSelector(), SelLocs, Params,
714a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios Kyrtzidis                                        DeclEndLoc);
715491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  if (SelLocsKind != SelLoc_NonStandard)
7165543169296beeb183b9c9392debc774fcf493eebDmitri Gribenko    return setParamsAndSelLocs(C, Params, llvm::None);
717491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
718491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  setParamsAndSelLocs(C, Params, SelLocs);
719491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis}
720491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
72157ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis/// \brief A definition will return its interface declaration.
72257ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis/// An interface declaration will return its definition.
72357ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis/// Otherwise it will return itself.
7246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesObjCMethodDecl *ObjCMethodDecl::getNextRedeclarationImpl() {
72557ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis  ASTContext &Ctx = getASTContext();
7266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCMethodDecl *Redecl = nullptr;
72772b2625aa67c8213acaf4bf6209b67859d60e2cfArgyrios Kyrtzidis  if (HasRedeclaration)
72872b2625aa67c8213acaf4bf6209b67859d60e2cfArgyrios Kyrtzidis    Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this));
729b40034c2e580ab3b08de9dfb738d8e5d8ef79136Argyrios Kyrtzidis  if (Redecl)
730b40034c2e580ab3b08de9dfb738d8e5d8ef79136Argyrios Kyrtzidis    return Redecl;
731b40034c2e580ab3b08de9dfb738d8e5d8ef79136Argyrios Kyrtzidis
73257ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis  Decl *CtxD = cast<Decl>(getDeclContext());
73357ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis
734df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis  if (!CtxD->isInvalidDecl()) {
735df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis    if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
736df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis      if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
737df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis        if (!ImplD->isInvalidDecl())
738df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis          Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
739df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis
740df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis    } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
741df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis      if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
742df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis        if (!ImplD->isInvalidDecl())
743df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis          Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
744df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis
745df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis    } else if (ObjCImplementationDecl *ImplD =
746df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis                 dyn_cast<ObjCImplementationDecl>(CtxD)) {
747df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis      if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
748df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis        if (!IFD->isInvalidDecl())
749df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis          Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
750df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis
751df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis    } else if (ObjCCategoryImplDecl *CImplD =
752df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis                 dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
753df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis      if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
754df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis        if (!CatD->isInvalidDecl())
755df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis          Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
756df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis    }
75757ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis  }
75857ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis
7593a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis  if (!Redecl && isRedeclaration()) {
7603a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis    // This is the last redeclaration, go back to the first method.
7613a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis    return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
7623a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis                                                    isInstanceMethod());
7633a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis  }
7643a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis
76557ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis  return Redecl ? Redecl : this;
76657ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis}
76757ea6bee79cc60ba20c7886b453f40f380dce1b1Argyrios Kyrtzidis
768e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios KyrtzidisObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
769e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis  Decl *CtxD = cast<Decl>(getDeclContext());
770e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis
771e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis  if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
772e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis    if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
773e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis      if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(),
774e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis                                              isInstanceMethod()))
775e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis        return MD;
776e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis
777e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis  } else if (ObjCCategoryImplDecl *CImplD =
778e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis               dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
7790d69b8cc8e90a9364771837cb42d7031b4cbb984Steve Naroff    if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
780e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis      if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
781e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis                                               isInstanceMethod()))
782e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis        return MD;
783e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis  }
784e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis
7856d4740e740f9c109c76c111cc90a63f6a24f6357Argyrios Kyrtzidis  if (isRedeclaration())
7866d4740e740f9c109c76c111cc90a63f6a24f6357Argyrios Kyrtzidis    return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
7876d4740e740f9c109c76c111cc90a63f6a24f6357Argyrios Kyrtzidis                                                    isInstanceMethod());
7886d4740e740f9c109c76c111cc90a63f6a24f6357Argyrios Kyrtzidis
789e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis  return this;
790e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis}
791e7f9d301a10b4b3223e91d9be4362b44cba0a212Argyrios Kyrtzidis
792a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios KyrtzidisSourceLocation ObjCMethodDecl::getLocEnd() const {
793a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios Kyrtzidis  if (Stmt *Body = getBody())
794a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios Kyrtzidis    return Body->getLocEnd();
795a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios Kyrtzidis  return DeclEndLoc;
796a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios Kyrtzidis}
797a0cff720d40f239fee0e5ecc8378122b456c1991Argyrios Kyrtzidis
79885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
79985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  ObjCMethodFamily family = static_cast<ObjCMethodFamily>(Family);
800d976c8e2752bc36c0697d43f985ec55b9450f8c1John McCall  if (family != static_cast<unsigned>(InvalidObjCMethodFamily))
80185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    return family;
80285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
803d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  // Check for an explicit attribute.
804d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  if (const ObjCMethodFamilyAttr *attr = getAttr<ObjCMethodFamilyAttr>()) {
805d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // The unfortunate necessity of mapping between enums here is due
806d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    // to the attributes framework.
807d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    switch (attr->getFamily()) {
808d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    case ObjCMethodFamilyAttr::OMF_None: family = OMF_None; break;
809d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    case ObjCMethodFamilyAttr::OMF_alloc: family = OMF_alloc; break;
810d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    case ObjCMethodFamilyAttr::OMF_copy: family = OMF_copy; break;
811d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    case ObjCMethodFamilyAttr::OMF_init: family = OMF_init; break;
812d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    case ObjCMethodFamilyAttr::OMF_mutableCopy: family = OMF_mutableCopy; break;
813d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    case ObjCMethodFamilyAttr::OMF_new: family = OMF_new; break;
814d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    }
815d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    Family = static_cast<unsigned>(family);
816d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall    return family;
817d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall  }
818d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall
81985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  family = getSelector().getMethodFamily();
82085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  switch (family) {
82185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  case OMF_None: break;
82285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
82385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // init only has a conventional meaning for an instance method, and
82485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // it has to return an object.
82585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  case OMF_init:
826651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (!isInstanceMethod() || !getReturnType()->isObjCObjectPointerType())
82785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall      family = OMF_None;
82885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    break;
82985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
83085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // alloc/copy/new have a conventional meaning for both class and
83185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // instance methods, but they require an object return.
83285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  case OMF_alloc:
83385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  case OMF_copy:
83485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  case OMF_mutableCopy:
83585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  case OMF_new:
836651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (!getReturnType()->isObjCObjectPointerType())
83785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall      family = OMF_None;
83885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    break;
83985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
84085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // These selectors have a conventional meaning only for instance methods.
84185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  case OMF_dealloc:
84280cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber  case OMF_finalize:
84385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  case OMF_retain:
84485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  case OMF_release:
84585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  case OMF_autorelease:
84685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  case OMF_retainCount:
847926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  case OMF_self:
84885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    if (!isInstanceMethod())
84985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall      family = OMF_None;
85085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall    break;
8519670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian
8529670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian  case OMF_performSelector:
853651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (!isInstanceMethod() || !getReturnType()->isObjCIdType())
8549670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian      family = OMF_None;
8559670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian    else {
8569670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian      unsigned noParams = param_size();
8579670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian      if (noParams < 1 || noParams > 3)
8589670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian        family = OMF_None;
8599670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian      else {
860651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        ObjCMethodDecl::param_type_iterator it = param_type_begin();
8619670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian        QualType ArgT = (*it);
8629670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian        if (!ArgT->isObjCSelType()) {
8639670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian          family = OMF_None;
8649670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian          break;
8659670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian        }
8669670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian        while (--noParams) {
8679670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian          it++;
8689670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian          ArgT = (*it);
8699670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian          if (!ArgT->isObjCIdType()) {
8709670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian            family = OMF_None;
8719670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian            break;
8729670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian          }
8739670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian        }
8749670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian      }
8759670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian    }
8769670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian    break;
8779670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian
87885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  }
87985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
88085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  // Cache the result.
88185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  Family = static_cast<unsigned>(family);
88285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall  return family;
88385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall}
88485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall
8851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid ObjCMethodDecl::createImplicitParams(ASTContext &Context,
886ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner                                          const ObjCInterfaceDecl *OID) {
887ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner  QualType selfTy;
888ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner  if (isInstanceMethod()) {
889ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    // There may be no interface context due to error in declaration
890ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    // of the interface (which has been reported). Recover gracefully.
891ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    if (OID) {
8923b3a45858c6b2a45114e91902c3bf3c4b7f5f302Daniel Dunbar      selfTy = Context.getObjCInterfaceType(OID);
89314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      selfTy = Context.getObjCObjectPointerType(selfTy);
894ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    } else {
895ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner      selfTy = Context.getObjCIdType();
896ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    }
897ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner  } else // we have a factory method.
898ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    selfTy = Context.getObjCClassType();
899ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
9007acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  bool selfIsPseudoStrong = false;
901f85e193739c953358c865005855253af4f68a497John McCall  bool selfIsConsumed = false;
9022bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek
9034e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (Context.getLangOpts().ObjCAutoRefCount) {
9042bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek    if (isInstanceMethod()) {
9052bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek      selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
9062bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek
9072bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek      // 'self' is always __strong.  It's actually pseudo-strong except
9082bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek      // in init methods (or methods labeled ns_consumes_self), though.
9092bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek      Qualifiers qs;
9102bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek      qs.setObjCLifetime(Qualifiers::OCL_Strong);
9112bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek      selfTy = Context.getQualifiedType(selfTy, qs);
9122bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek
9132bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek      // In addition, 'self' is const unless this is an init method.
9142bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek      if (getMethodFamily() != OMF_init && !selfIsConsumed) {
9152bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek        selfTy = selfTy.withConst();
9162bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek        selfIsPseudoStrong = true;
9172bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek      }
9182bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek    }
9192bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek    else {
9202bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek      assert(isClassMethod());
9212bbcd5ce370753c86d312d2c72a97476ac35b073Ted Kremenek      // 'self' is always const in class methods.
922f85e193739c953358c865005855253af4f68a497John McCall      selfTy = selfTy.withConst();
9237acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall      selfIsPseudoStrong = true;
9247acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall    }
925f85e193739c953358c865005855253af4f68a497John McCall  }
926f85e193739c953358c865005855253af4f68a497John McCall
927f85e193739c953358c865005855253af4f68a497John McCall  ImplicitParamDecl *self
928f85e193739c953358c865005855253af4f68a497John McCall    = ImplicitParamDecl::Create(Context, this, SourceLocation(),
929f85e193739c953358c865005855253af4f68a497John McCall                                &Context.Idents.get("self"), selfTy);
930f85e193739c953358c865005855253af4f68a497John McCall  setSelfDecl(self);
931f85e193739c953358c865005855253af4f68a497John McCall
932f85e193739c953358c865005855253af4f68a497John McCall  if (selfIsConsumed)
933651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    self->addAttr(NSConsumedAttr::CreateImplicit(Context));
934ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
9357acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  if (selfIsPseudoStrong)
9367acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall    self->setARCPseudoStrong(true);
9377acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall
9381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
9391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                       &Context.Idents.get("_cmd"),
94053c9d8a4b8f0a76cb9dd2fdd8c433ccf110f2eecSteve Naroff                                       Context.getObjCSelType()));
941ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner}
942ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
943ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris LattnerObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
944ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner  if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
945ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    return ID;
946ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner  if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
947ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    return CD->getClassInterface();
948a8530375168f578e9039837c58054d55655c981bArgyrios Kyrtzidis  if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
949ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    return IMD->getClassInterface();
950651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (isa<ObjCProtocolDecl>(getDeclContext()))
9516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
952b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie  llvm_unreachable("unknown method context");
953ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner}
954ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
955740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidisstatic void CollectOverriddenMethodsRecurse(const ObjCContainerDecl *Container,
956740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis                                            const ObjCMethodDecl *Method,
957740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis                               SmallVectorImpl<const ObjCMethodDecl *> &Methods,
958740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis                                            bool MovedToSuper) {
959740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  if (!Container)
960740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    return;
961740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
962740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  // In categories look for overriden methods from protocols. A method from
963740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  // category is not "overriden" since it is considered as the "same" method
964740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  // (same USR) as the one from the interface.
965740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  if (const ObjCCategoryDecl *
966740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis        Category = dyn_cast<ObjCCategoryDecl>(Container)) {
967740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    // Check whether we have a matching method at this category but only if we
968740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    // are at the super class level.
969740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    if (MovedToSuper)
970740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis      if (ObjCMethodDecl *
971740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis            Overridden = Container->getMethod(Method->getSelector(),
97204593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis                                              Method->isInstanceMethod(),
97304593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis                                              /*AllowHidden=*/true))
974740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis        if (Method != Overridden) {
975740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis          // We found an override at this category; there is no need to look
976740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis          // into its protocols.
977740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis          Methods.push_back(Overridden);
978740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis          return;
979740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis        }
980740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
981651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *P : Category->protocols())
982651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
983740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    return;
984740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  }
985740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
986740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  // Check whether we have a matching method at this level.
987740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  if (const ObjCMethodDecl *
988740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis        Overridden = Container->getMethod(Method->getSelector(),
98904593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis                                          Method->isInstanceMethod(),
99004593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis                                          /*AllowHidden=*/true))
991740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    if (Method != Overridden) {
992740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis      // We found an override at this level; there is no need to look
993740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis      // into other protocols or categories.
994740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis      Methods.push_back(Overridden);
995740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis      return;
996740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    }
997740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
998740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  if (const ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)){
999651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *P : Protocol->protocols())
1000651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1001740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  }
1002740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
1003740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  if (const ObjCInterfaceDecl *
1004740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis        Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
1005651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *P : Interface->protocols())
1006651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
1007651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1008651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *Cat : Interface->known_categories())
1009651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      CollectOverriddenMethodsRecurse(Cat, Method, Methods, MovedToSuper);
1010740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
1011740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    if (const ObjCInterfaceDecl *Super = Interface->getSuperClass())
1012740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis      return CollectOverriddenMethodsRecurse(Super, Method, Methods,
1013740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis                                             /*MovedToSuper=*/true);
1014740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  }
1015740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis}
1016740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
1017740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidisstatic inline void CollectOverriddenMethods(const ObjCContainerDecl *Container,
1018740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis                                            const ObjCMethodDecl *Method,
1019740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis                             SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
1020740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  CollectOverriddenMethodsRecurse(Container, Method, Methods,
1021740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis                                  /*MovedToSuper=*/false);
1022740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis}
1023740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
1024740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidisstatic void collectOverriddenMethodsSlow(const ObjCMethodDecl *Method,
1025740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis                          SmallVectorImpl<const ObjCMethodDecl *> &overridden) {
1026740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  assert(Method->isOverriding());
1027740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
1028740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  if (const ObjCProtocolDecl *
1029740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis        ProtD = dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) {
1030740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    CollectOverriddenMethods(ProtD, Method, overridden);
1031740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
1032740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  } else if (const ObjCImplDecl *
1033740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis               IMD = dyn_cast<ObjCImplDecl>(Method->getDeclContext())) {
1034740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    const ObjCInterfaceDecl *ID = IMD->getClassInterface();
1035740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    if (!ID)
1036740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis      return;
1037740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    // Start searching for overridden methods using the method from the
1038740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    // interface as starting point.
1039740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
104004593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis                                                    Method->isInstanceMethod(),
104104593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis                                                    /*AllowHidden=*/true))
1042740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis      Method = IFaceMeth;
1043740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    CollectOverriddenMethods(ID, Method, overridden);
1044740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
1045740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  } else if (const ObjCCategoryDecl *
1046740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis               CatD = dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) {
1047740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    const ObjCInterfaceDecl *ID = CatD->getClassInterface();
1048740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    if (!ID)
1049740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis      return;
1050740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    // Start searching for overridden methods using the method from the
1051740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    // interface as starting point.
1052740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
105304593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis                                                     Method->isInstanceMethod(),
105404593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis                                                     /*AllowHidden=*/true))
1055740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis      Method = IFaceMeth;
1056740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    CollectOverriddenMethods(ID, Method, overridden);
1057740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
1058740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  } else {
1059740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    CollectOverriddenMethods(
1060740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis                  dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()),
1061740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis                  Method, overridden);
1062740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  }
1063740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis}
1064740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
1065740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidisvoid ObjCMethodDecl::getOverriddenMethods(
1066740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis                    SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const {
1067740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  const ObjCMethodDecl *Method = this;
1068740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
1069740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  if (Method->isRedeclaration()) {
1070740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    Method = cast<ObjCContainerDecl>(Method->getDeclContext())->
1071740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis                   getMethod(Method->getSelector(), Method->isInstanceMethod());
1072740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  }
1073740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
1074e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis  if (Method->isOverriding()) {
1075740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    collectOverriddenMethodsSlow(Method, Overridden);
1076740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis    assert(!Overridden.empty() &&
1077740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis           "ObjCMethodDecl's overriding bit is not as expected");
1078740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis  }
1079740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis}
1080740ae67dbf8dac44dbc8d6593a60f4f37a0a2aa5Argyrios Kyrtzidis
108104bec39d61f2b392d798882c9141fecf3ca653c5Jordan Roseconst ObjCPropertyDecl *
108204bec39d61f2b392d798882c9141fecf3ca653c5Jordan RoseObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
108304bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  Selector Sel = getSelector();
108404bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  unsigned NumArgs = Sel.getNumArgs();
108504bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  if (NumArgs > 1)
10866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
108704bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose
108850d2b268d7a49719fe9dae89195ff809c4572dbfJordan Rose  if (!isInstanceMethod() || getMethodFamily() != OMF_None)
10896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
10906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
109104bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  if (isPropertyAccessor()) {
109204bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose    const ObjCContainerDecl *Container = cast<ObjCContainerDecl>(getParent());
1093c328d9c22a4397dd7313d06be5b82d700297b246Fariborz Jahanian    // If container is class extension, find its primary class.
1094c328d9c22a4397dd7313d06be5b82d700297b246Fariborz Jahanian    if (const ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(Container))
1095c328d9c22a4397dd7313d06be5b82d700297b246Fariborz Jahanian      if (CatDecl->IsClassExtension())
1096c328d9c22a4397dd7313d06be5b82d700297b246Fariborz Jahanian        Container = CatDecl->getClassInterface();
1097c328d9c22a4397dd7313d06be5b82d700297b246Fariborz Jahanian
109804bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose    bool IsGetter = (NumArgs == 0);
109904bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose
1100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *I : Container->properties()) {
1101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Selector NextSel = IsGetter ? I->getGetterName()
1102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                  : I->getSetterName();
110304bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose      if (NextSel == Sel)
1104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        return I;
110504bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose    }
110604bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose
110704bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose    llvm_unreachable("Marked as a property accessor but no property found!");
110804bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  }
110904bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose
111004bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  if (!CheckOverrides)
11116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
111204bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose
111304bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  typedef SmallVector<const ObjCMethodDecl *, 8> OverridesTy;
111404bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  OverridesTy Overrides;
111504bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  getOverriddenMethods(Overrides);
111604bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  for (OverridesTy::const_iterator I = Overrides.begin(), E = Overrides.end();
111704bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose       I != E; ++I) {
111804bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose    if (const ObjCPropertyDecl *Prop = (*I)->findPropertyDecl(false))
111904bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose      return Prop;
112004bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose  }
112104bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose
11226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
112304bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose}
112404bec39d61f2b392d798882c9141fecf3ca653c5Jordan Rose
1125ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
1126ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner// ObjCInterfaceDecl
1127ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
11280b7ebb3dba0df0a6cbf221e5edbc6a4b8848478cChris Lattner
1129a6ea10e22b600d92e084f6b11b9b9a92d0eb2412Douglas GregorObjCInterfaceDecl *ObjCInterfaceDecl::Create(const ASTContext &C,
1130d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor                                             DeclContext *DC,
11310ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner                                             SourceLocation atLoc,
11321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             IdentifierInfo *Id,
11330af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor                                             ObjCInterfaceDecl *PrevDecl,
1134d6a07aaf62b40cdfbd96f6b874d02b06fc22d015Steve Naroff                                             SourceLocation ClassLoc,
11357723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor                                             bool isInternal){
1136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ObjCInterfaceDecl *Result = new (C, DC)
11376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      ObjCInterfaceDecl(C, DC, atLoc, Id, ClassLoc, PrevDecl, isInternal);
11386bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  Result->Data.setInt(!C.getLangOpts().Modules);
11390af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor  C.getObjCInterfaceType(Result, PrevDecl);
11400af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor  return Result;
11410af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor}
11420af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor
11436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C,
11441e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                         unsigned ID) {
11456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCInterfaceDecl *Result = new (C, ID) ObjCInterfaceDecl(C, nullptr,
11466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                                            SourceLocation(),
11476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                                            nullptr,
11486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                                            SourceLocation(),
11496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                                            nullptr, false);
11506bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  Result->Data.setInt(!C.getLangOpts().Modules);
11516bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  return Result;
11520e77ba0bf769e2e5a4a93c079f241b02aeb3ef93Chris Lattner}
11536c4ae5de0c356777446f823b573821fb95560d91Chris Lattner
11546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesObjCInterfaceDecl::ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC,
11556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                     SourceLocation AtLoc, IdentifierInfo *Id,
11566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                     SourceLocation CLoc,
11576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                     ObjCInterfaceDecl *PrevDecl,
11586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                     bool IsInternal)
11596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc),
11606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      redeclarable_base(C), TypeForDecl(nullptr), Data() {
1161bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola  setPreviousDecl(PrevDecl);
1162fd002a7027e47ddd4bc9f32b158b18ab0ebd29c7Douglas Gregor
1163fd002a7027e47ddd4bc9f32b158b18ab0ebd29c7Douglas Gregor  // Copy the 'data' pointer over.
1164fd002a7027e47ddd4bc9f32b158b18ab0ebd29c7Douglas Gregor  if (PrevDecl)
1165fd002a7027e47ddd4bc9f32b158b18ab0ebd29c7Douglas Gregor    Data = PrevDecl->Data;
1166fd002a7027e47ddd4bc9f32b158b18ab0ebd29c7Douglas Gregor
11676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  setImplicit(IsInternal);
1168e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff}
1169e4f039e01e797a38bc97bf22aff9832ecd18ff5fSteve Naroff
117026ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregorvoid ObjCInterfaceDecl::LoadExternalDefinition() const {
11712e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  assert(data().ExternallyCompleted && "Class is not externally completed");
11722e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  data().ExternallyCompleted = false;
117326ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor  getASTContext().getExternalSource()->CompleteType(
117426ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor                                        const_cast<ObjCInterfaceDecl *>(this));
117526ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor}
117626ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor
117726ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregorvoid ObjCInterfaceDecl::setExternallyCompleted() {
117826ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor  assert(getASTContext().getExternalSource() &&
117926ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor         "Class can't be externally completed without an external source");
11802e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  assert(hasDefinition() &&
118126ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor         "Forward declarations can't be externally completed");
11822e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  data().ExternallyCompleted = true;
118326ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor}
118426ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor
1185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid ObjCInterfaceDecl::setHasDesignatedInitializers() {
1186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Check for a complete definition and recover if not so.
1187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!isThisDeclarationADefinition())
1188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return;
1189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  data().HasDesignatedInitializers = true;
1190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
1191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesbool ObjCInterfaceDecl::hasDesignatedInitializers() const {
1193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Check for a complete definition and recover if not so.
1194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!isThisDeclarationADefinition())
1195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return false;
1196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (data().ExternallyCompleted)
1197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    LoadExternalDefinition();
1198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return data().HasDesignatedInitializers;
1200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
1201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
12028a1d722f13df383600f36d77f842957c8adb5f1bArgyrios KyrtzidisObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
12037723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor  if (const ObjCInterfaceDecl *Def = getDefinition()) {
12047723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor    if (data().ExternallyCompleted)
12057723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor      LoadExternalDefinition();
12067723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor
12077723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor    return getASTContext().getObjCImplementation(
12087723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor             const_cast<ObjCInterfaceDecl*>(Def));
12097723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor  }
12107723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor
12112e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  // FIXME: Should make sure no callers ever do this.
12126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
12138a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis}
12148a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
12158a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidisvoid ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
12167723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor  getASTContext().setObjCImplementation(getDefinition(), ImplD);
12178a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis}
12188a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
12192c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahaniannamespace {
12202c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian  struct SynthesizeIvarChunk {
12212c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian    uint64_t Size;
12222c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian    ObjCIvarDecl *Ivar;
12232c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian    SynthesizeIvarChunk(uint64_t size, ObjCIvarDecl *ivar)
12242c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian      : Size(size), Ivar(ivar) {}
12252c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian  };
12262c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian
12272c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian  bool operator<(const SynthesizeIvarChunk & LHS,
12282c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian                 const SynthesizeIvarChunk &RHS) {
12292c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian      return LHS.Size < RHS.Size;
12302c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian  }
12312c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian}
12322c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian
12332c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian/// all_declared_ivar_begin - return first ivar declared in this class,
12342c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian/// its extensions and its implementation. Lazily build the list on first
12352c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian/// access.
12364919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl///
12374919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl/// Caveat: The list returned by this method reflects the current
12384919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl/// state of the parser. The cache will be updated for every ivar
12394919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl/// added by an extension or the implementation when they are
12404919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl/// encountered.
12414919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl/// See also ObjCIvarDecl::Create().
12422c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz JahanianObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
12432e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  // FIXME: Should make sure no callers ever do this.
12442e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  if (!hasDefinition())
12456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
12466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
12476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCIvarDecl *curIvar = nullptr;
12484919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl  if (!data().IvarList) {
12494919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl    if (!ivar_empty()) {
12504919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl      ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
12514919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl      data().IvarList = *I; ++I;
12524919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl      for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
12534919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl        curIvar->setNextIvar(*I);
12544919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl    }
1255d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *Ext : known_extensions()) {
12574919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl      if (!Ext->ivar_empty()) {
12584919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl        ObjCCategoryDecl::ivar_iterator
12594919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl          I = Ext->ivar_begin(),
12604919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl          E = Ext->ivar_end();
12614919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl        if (!data().IvarList) {
12624919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl          data().IvarList = *I; ++I;
12634919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl          curIvar = data().IvarList;
12644919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl        }
12654919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl        for ( ;I != E; curIvar = *I, ++I)
12664919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl          curIvar->setNextIvar(*I);
12672c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian      }
12682c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian    }
12694919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl    data().IvarListMissingImplementation = true;
12702c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian  }
12714919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl
12724919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl  // cached and complete!
12734919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl  if (!data().IvarListMissingImplementation)
12744919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl      return data().IvarList;
12752c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian
12762c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian  if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
12774919de6a53a007487c6d6b173921b5e7152a2004Adrian Prantl    data().IvarListMissingImplementation = false;
12782c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian    if (!ImplDecl->ivar_empty()) {
12792c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian      SmallVector<SynthesizeIvarChunk, 16> layout;
1280651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      for (auto *IV : ImplDecl->ivars()) {
12812c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian        if (IV->getSynthesize() && !IV->isInvalidDecl()) {
12822c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian          layout.push_back(SynthesizeIvarChunk(
12832c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian                             IV->getASTContext().getTypeSize(IV->getType()), IV));
12842c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian          continue;
12852c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian        }
12862c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian        if (!data().IvarList)
1287651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          data().IvarList = IV;
12882c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian        else
1289651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          curIvar->setNextIvar(IV);
1290651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        curIvar = IV;
12912c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian      }
12922c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian
12932c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian      if (!layout.empty()) {
12942c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian        // Order synthesized ivars by their size.
12952c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian        std::stable_sort(layout.begin(), layout.end());
12962c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian        unsigned Ix = 0, EIx = layout.size();
12972c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian        if (!data().IvarList) {
12982c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian          data().IvarList = layout[0].Ivar; Ix++;
12992c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian          curIvar = data().IvarList;
13002c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian        }
13012c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian        for ( ; Ix != EIx; curIvar = layout[Ix].Ivar, Ix++)
13022c5d8459f12549dc48654a4da33c085835831d1dFariborz Jahanian          curIvar->setNextIvar(layout[Ix].Ivar);
13032c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian      }
13042c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian    }
13052c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian  }
13062e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  return data().IvarList;
13072c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian}
13088a779314870760848e61da2c428a78971fe3f1c3Ted Kremenek
1309ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner/// FindCategoryDeclaration - Finds category declaration in the list of
1310ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner/// categories for this class and returns it. Name of the category is passed
1311ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner/// in 'CategoryId'. If category not found, return 0;
1312ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner///
1313ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris LattnerObjCCategoryDecl *
1314ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris LattnerObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
13155a61e0c4229dc82617a37a68ac2fc08d46e00488Argyrios Kyrtzidis  // FIXME: Should make sure no callers ever do this.
13165a61e0c4229dc82617a37a68ac2fc08d46e00488Argyrios Kyrtzidis  if (!hasDefinition())
13176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
13185a61e0c4229dc82617a37a68ac2fc08d46e00488Argyrios Kyrtzidis
13192e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  if (data().ExternallyCompleted)
132026ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor    LoadExternalDefinition();
132126ac3f30ecef21749c00a4b1a08dd15d772dd5aaDouglas Gregor
1322651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *Cat : visible_categories())
1323d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    if (Cat->getIdentifier() == CategoryId)
1324651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return Cat;
13256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
13266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
1327ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner}
1328ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
13291cb35dd4840d21cec58648361180d5688446a9caArgyrios KyrtzidisObjCMethodDecl *
13301cb35dd4840d21cec58648361180d5688446a9caArgyrios KyrtzidisObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
1331651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *Cat : visible_categories()) {
1332d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
13331cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis      if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
13341cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis        return MD;
1335d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  }
1336d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
13376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
13381cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis}
13391cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis
13401cb35dd4840d21cec58648361180d5688446a9caArgyrios KyrtzidisObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
1341651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *Cat : visible_categories()) {
1342d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
13431cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis      if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
13441cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis        return MD;
1345d329724745b49f894b768d47275b7c2713106e89Douglas Gregor  }
13466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
13476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
13481cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis}
13491cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis
13500fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian/// ClassImplementsProtocol - Checks that 'lProto' protocol
13510fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian/// has been implemented in IDecl class, its super class or categories (if
13520fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian/// lookupCategory is true).
13530fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanianbool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
13540fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian                                    bool lookupCategory,
13550fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian                                    bool RHSIsQualifiedID) {
13562e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  if (!hasDefinition())
13572e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    return false;
13582e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
13590fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  ObjCInterfaceDecl *IDecl = this;
13600fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  // 1st, look up the class.
1361651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *PI : IDecl->protocols()){
1362651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
13630fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian      return true;
13640fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian    // This is dubious and is added to be compatible with gcc.  In gcc, it is
13650fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian    // also allowed assigning a protocol-qualified 'id' type to a LHS object
13660fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian    // when protocol in qualified LHS is in list of protocols in the rhs 'id'
13670fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian    // object. This IMO, should be a bug.
13680fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian    // FIXME: Treat this as an extension, and flag this as an error when GCC
13690fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian    // extensions are not enabled.
13701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (RHSIsQualifiedID &&
1371651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        getASTContext().ProtocolCompatibleWithProtocol(PI, lProto))
13720fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian      return true;
13730fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  }
13741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13750fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  // 2nd, look up the category.
13760fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  if (lookupCategory)
1377651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *Cat : visible_categories()) {
1378651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      for (auto *PI : Cat->protocols())
1379651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
13800fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian          return true;
13810fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian    }
13821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13830fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  // 3rd, look up the super class(s)
13840fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  if (IDecl->getSuperClass())
13850fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian    return
13860fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
13870fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian                                                  RHSIsQualifiedID);
13881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13890fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian  return false;
13900fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian}
13910fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian
1392ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
1393ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner// ObjCIvarDecl
1394ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
1395ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
139699ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid ObjCIvarDecl::anchor() { }
139799ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
1398a06549226f45d5b72169a3d054415616dd1014a2Daniel DunbarObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
1399ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                   SourceLocation StartLoc,
1400ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                   SourceLocation IdLoc, IdentifierInfo *Id,
1401a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall                                   QualType T, TypeSourceInfo *TInfo,
1402ad51e74030a59a8aa4ef0ebca1d7a701602ef53bFariborz Jahanian                                   AccessControl ac, Expr *BW,
1403651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   bool synthesized) {
1404a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar  if (DC) {
1405a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar    // Ivar's can only appear in interfaces, implementations (via synthesized
1406a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar    // properties), and class extensions (via direct declaration, or synthesized
1407a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar    // properties).
1408a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar    //
1409a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar    // FIXME: This should really be asserting this:
1410a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar    //   (isa<ObjCCategoryDecl>(DC) &&
1411a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar    //    cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
1412a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar    // but unfortunately we sometimes place ivars into non-class extension
1413a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar    // categories on error. This breaks an AST invariant, and should not be
1414a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar    // fixed.
1415a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar    assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
1416a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar            isa<ObjCCategoryDecl>(DC)) &&
1417a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar           "Invalid ivar decl context!");
14182c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian    // Once a new ivar is created in any of class/class-extension/implementation
14192c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian    // decl contexts, the previously built IvarList must be rebuilt.
14202c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian    ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(DC);
14212c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian    if (!ID) {
1422ffb0c3adc27d257c8453886957b8d220d1ad14d8Eric Christopher      if (ObjCImplementationDecl *IM = dyn_cast<ObjCImplementationDecl>(DC))
14232c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian        ID = IM->getClassInterface();
1424ffb0c3adc27d257c8453886957b8d220d1ad14d8Eric Christopher      else
1425ffb0c3adc27d257c8453886957b8d220d1ad14d8Eric Christopher        ID = cast<ObjCCategoryDecl>(DC)->getClassInterface();
14262c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian    }
14276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    ID->setIvarList(nullptr);
1428a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar  }
1429a06549226f45d5b72169a3d054415616dd1014a2Daniel Dunbar
1430651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW,
1431651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                  synthesized);
14326c4ae5de0c356777446f823b573821fb95560d91Chris Lattner}
14336c4ae5de0c356777446f823b573821fb95560d91Chris Lattner
14341e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas GregorObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
14356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(),
14366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                  nullptr, QualType(), nullptr,
14376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                  ObjCIvarDecl::None, nullptr, false);
14381e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor}
14391e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
144027a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbarconst ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
144127a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar  const ObjCContainerDecl *DC = cast<ObjCContainerDecl>(getDeclContext());
144227a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar
144327a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar  switch (DC->getKind()) {
144427a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar  default:
144527a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar  case ObjCCategoryImpl:
144627a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar  case ObjCProtocol:
1447b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie    llvm_unreachable("invalid ivar container!");
144827a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar
144927a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar    // Ivars can only appear in class extension categories.
145027a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar  case ObjCCategory: {
145127a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar    const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(DC);
145227a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar    assert(CD->IsClassExtension() && "invalid container for ivar!");
145327a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar    return CD->getClassInterface();
145427a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar  }
145527a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar
145627a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar  case ObjCImplementation:
145727a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar    return cast<ObjCImplementationDecl>(DC)->getClassInterface();
145801e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek
145927a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar  case ObjCInterface:
146027a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar    return cast<ObjCInterfaceDecl>(DC);
146127a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar  }
146227a961a6adab85cfcf7e48485bbec9237719ae96Daniel Dunbar}
1463ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
1464ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
1465ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner// ObjCAtDefsFieldDecl
1466ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
1467ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
146899ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid ObjCAtDefsFieldDecl::anchor() { }
146999ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
147001e6779faca1e3a3164c697d6e2dfee0881a6981Ted KremenekObjCAtDefsFieldDecl
1471ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
1472ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                             SourceLocation StartLoc,  SourceLocation IdLoc,
147301e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek                             IdentifierInfo *Id, QualType T, Expr *BW) {
1474651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
147501e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek}
147601e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek
1477651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
14781e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                             unsigned ID) {
14796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(),
14806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                         SourceLocation(), nullptr, QualType(),
14816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                         nullptr);
14821e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor}
14831e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
1484ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
1485ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner// ObjCProtocolDecl
1486ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
1487ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
148899ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid ObjCProtocolDecl::anchor() { }
148999ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
14906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesObjCProtocolDecl::ObjCProtocolDecl(ASTContext &C, DeclContext *DC,
14916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                   IdentifierInfo *Id, SourceLocation nameLoc,
149227c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor                                   SourceLocation atStartLoc,
1493c9d3c7edb513e9b8a6ab65b04133653e71d7a72bDouglas Gregor                                   ObjCProtocolDecl *PrevDecl)
14946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc),
14956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      redeclarable_base(C), Data() {
1496bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola  setPreviousDecl(PrevDecl);
149727c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor  if (PrevDecl)
149827c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    Data = PrevDecl->Data;
149927c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor}
150027c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor
1501d04341000d35c8808a72838b057eed7bf13b7661Douglas GregorObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
15021711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                                           IdentifierInfo *Id,
15031711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                                           SourceLocation nameLoc,
1504b05d7b20171bbd2feb14b059f39332cbe1bf1014Argyrios Kyrtzidis                                           SourceLocation atStartLoc,
1505c9d3c7edb513e9b8a6ab65b04133653e71d7a72bDouglas Gregor                                           ObjCProtocolDecl *PrevDecl) {
1506651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ObjCProtocolDecl *Result =
15076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      new (C, DC) ObjCProtocolDecl(C, DC, Id, nameLoc, atStartLoc, PrevDecl);
15086bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  Result->Data.setInt(!C.getLangOpts().Modules);
150927c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor  return Result;
1510cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner}
1511cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner
1512651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C,
15131e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                       unsigned ID) {
1514651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ObjCProtocolDecl *Result =
15156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(),
15166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                   SourceLocation(), nullptr);
15176bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  Result->Data.setInt(!C.getLangOpts().Modules);
15186bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  return Result;
15191e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor}
15201e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
152191b0b0cf6b537cbcbca0038c7032f87161a41d31Steve NaroffObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
152291b0b0cf6b537cbcbca0038c7032f87161a41d31Steve Naroff  ObjCProtocolDecl *PDecl = this;
152391b0b0cf6b537cbcbca0038c7032f87161a41d31Steve Naroff
152491b0b0cf6b537cbcbca0038c7032f87161a41d31Steve Naroff  if (Name == getIdentifier())
152591b0b0cf6b537cbcbca0038c7032f87161a41d31Steve Naroff    return PDecl;
152691b0b0cf6b537cbcbca0038c7032f87161a41d31Steve Naroff
1527651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *I : protocols())
1528651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if ((PDecl = I->lookupProtocolNamed(Name)))
152991b0b0cf6b537cbcbca0038c7032f87161a41d31Steve Naroff      return PDecl;
15301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
153291b0b0cf6b537cbcbca0038c7032f87161a41d31Steve Naroff}
153391b0b0cf6b537cbcbca0038c7032f87161a41d31Steve Naroff
1534094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis// lookupMethod - Lookup a instance/class method in the protocol and protocols
1535ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner// it inherited.
1536094e2bb6730d63e0f6919e4839522a43b7644181Argyrios KyrtzidisObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
1537094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis                                               bool isInstance) const {
15386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCMethodDecl *MethodDecl = nullptr;
15391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15400f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor  // If there is no definition or the definition is hidden, we don't find
15410f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor  // anything.
15420f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor  const ObjCProtocolDecl *Def = getDefinition();
15430f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor  if (!Def || Def->isHidden())
15446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
15450f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor
1546094e2bb6730d63e0f6919e4839522a43b7644181Argyrios Kyrtzidis  if ((MethodDecl = getMethod(Sel, isInstance)))
1547ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    return MethodDecl;
15481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1549651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *I : protocols())
1550651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
1551ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner      return MethodDecl;
15526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
1553ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner}
1554411280e5b25ba7dcd7c8a82a5c23880fe7632a3cChris Lattner
15555e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregorvoid ObjCProtocolDecl::allocateDefinitionData() {
15566bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  assert(!Data.getPointer() && "Protocol already has a definition!");
15576bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  Data.setPointer(new (getASTContext()) DefinitionData);
15586bd992946bda92193fadce7e4890d4465d2702f4Douglas Gregor  Data.getPointer()->Definition = this;
15595e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor}
15605e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor
15615e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregorvoid ObjCProtocolDecl::startDefinition() {
15625e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor  allocateDefinitionData();
15631d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor
15641d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor  // Update all of the declarations with a pointer to the definition.
1565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto RD : redecls())
15661d784b277cdfd4eba03680715d2a082b3f28d295Douglas Gregor    RD->Data = this->Data;
1567ad834d534e9a5db3d3baa09593775f83ceaff1f2Argyrios Kyrtzidis}
1568ad834d534e9a5db3d3baa09593775f83ceaff1f2Argyrios Kyrtzidis
1569cfaed8d399a34e79fbab9f70eb4ea1bbeb81a02bFariborz Jahanianvoid ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM,
1570cfaed8d399a34e79fbab9f70eb4ea1bbeb81a02bFariborz Jahanian                                                    PropertyDeclOrder &PO) const {
1571cc5a28a1a10e966ae176957d9fd21b03951f600eFariborz Jahanian
1572cc5a28a1a10e966ae176957d9fd21b03951f600eFariborz Jahanian  if (const ObjCProtocolDecl *PDecl = getDefinition()) {
1573651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (auto *Prop : PDecl->properties()) {
1574cc5a28a1a10e966ae176957d9fd21b03951f600eFariborz Jahanian      // Insert into PM if not there already.
1575cc5a28a1a10e966ae176957d9fd21b03951f600eFariborz Jahanian      PM.insert(std::make_pair(Prop->getIdentifier(), Prop));
1576cfaed8d399a34e79fbab9f70eb4ea1bbeb81a02bFariborz Jahanian      PO.push_back(Prop);
1577cc5a28a1a10e966ae176957d9fd21b03951f600eFariborz Jahanian    }
1578cc5a28a1a10e966ae176957d9fd21b03951f600eFariborz Jahanian    // Scan through protocol's protocols.
1579651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *PI : PDecl->protocols())
1580651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      PI->collectPropertiesToImplement(PM, PO);
1581b36ea375e20f71df19c101fa2399b7ea3a607e04Anna Zaks  }
1582b36ea375e20f71df19c101fa2399b7ea3a607e04Anna Zaks}
1583b36ea375e20f71df19c101fa2399b7ea3a607e04Anna Zaks
15848dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian
15858dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanianvoid ObjCProtocolDecl::collectInheritedProtocolProperties(
15868dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian                                                const ObjCPropertyDecl *Property,
15878dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian                                                ProtocolPropertyMap &PM) const {
15888dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian  if (const ObjCProtocolDecl *PDecl = getDefinition()) {
15898dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian    bool MatchFound = false;
1590651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (auto *Prop : PDecl->properties()) {
15918dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian      if (Prop == Property)
15928dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian        continue;
15938dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian      if (Prop->getIdentifier() == Property->getIdentifier()) {
15948dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian        PM[PDecl] = Prop;
15958dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian        MatchFound = true;
15968dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian        break;
15978dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian      }
15988dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian    }
15998dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian    // Scan through protocol's protocols which did not have a matching property.
16008dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian    if (!MatchFound)
1601651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      for (const auto *PI : PDecl->protocols())
1602651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        PI->collectInheritedProtocolProperties(Property, PM);
16038dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian  }
16048dbda516d343706bae904f800c6d64e145d58a8cFariborz Jahanian}
1605b36ea375e20f71df19c101fa2399b7ea3a607e04Anna Zaks
1606ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
1607ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner// ObjCCategoryDecl
1608ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
1609ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
161099ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid ObjCCategoryDecl::anchor() { }
161199ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
1612d04341000d35c8808a72838b057eed7bf13b7661Douglas GregorObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
1613651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                           SourceLocation AtLoc,
16143db211b617c5073aa70eb25d37ed44ae0dca17c4Douglas Gregor                                           SourceLocation ClassNameLoc,
16153db211b617c5073aa70eb25d37ed44ae0dca17c4Douglas Gregor                                           SourceLocation CategoryNameLoc,
1616955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis                                           IdentifierInfo *Id,
1617af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                                           ObjCInterfaceDecl *IDecl,
1618af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                                           SourceLocation IvarLBraceLoc,
1619af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                                           SourceLocation IvarRBraceLoc) {
1620651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ObjCCategoryDecl *CatDecl =
1621651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id,
1622651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   IDecl, IvarLBraceLoc, IvarRBraceLoc);
1623955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis  if (IDecl) {
1624955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis    // Link this category into its class's category list.
1625d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    CatDecl->NextClassCategory = IDecl->getCategoryListRaw();
16262e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (IDecl->hasDefinition()) {
1627d329724745b49f894b768d47275b7c2713106e89Douglas Gregor      IDecl->setCategoryListRaw(CatDecl);
16282e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor      if (ASTMutationListener *L = C.getASTMutationListener())
16292e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor        L->AddedObjCCategoryToInterface(CatDecl, IDecl);
16302e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    }
1631955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis  }
1632955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis
1633955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis  return CatDecl;
1634955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis}
1635955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis
1636651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C,
16371e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                       unsigned ID) {
16386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(),
16396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                      SourceLocation(), SourceLocation(),
16406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                      nullptr, nullptr);
164161f9d41036e30ff80130f99b31c0626e3ef057ccChris Lattner}
164261f9d41036e30ff80130f99b31c0626e3ef057ccChris Lattner
16438a1d722f13df383600f36d77f842957c8adb5f1bArgyrios KyrtzidisObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
16448a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  return getASTContext().getObjCImplementation(
16458a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis                                           const_cast<ObjCCategoryDecl*>(this));
16468a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis}
16478a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
16488a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidisvoid ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
16498a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  getASTContext().setObjCImplementation(this, ImplD);
16508a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis}
16518a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
16528a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
1653ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
1654ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner// ObjCCategoryImplDecl
1655ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
1656ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner
165799ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid ObjCCategoryImplDecl::anchor() { }
165899ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
165975c9cae5f85c72cbb1649e93849e16ede3f07522Chris LattnerObjCCategoryImplDecl *
1660d04341000d35c8808a72838b057eed7bf13b7661Douglas GregorObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
16611711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                             IdentifierInfo *Id,
16621711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                             ObjCInterfaceDecl *ClassInterface,
16631711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                             SourceLocation nameLoc,
1664c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis                             SourceLocation atStartLoc,
1665c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis                             SourceLocation CategoryNameLoc) {
1666712ef874534ee1bef41d1aa4664ae36148ec8b12Fariborz Jahanian  if (ClassInterface && ClassInterface->hasDefinition())
1667712ef874534ee1bef41d1aa4664ae36148ec8b12Fariborz Jahanian    ClassInterface = ClassInterface->getDefinition();
1668651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return new (C, DC) ObjCCategoryImplDecl(DC, Id, ClassInterface, nameLoc,
1669651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                          atStartLoc, CategoryNameLoc);
167075c9cae5f85c72cbb1649e93849e16ede3f07522Chris Lattner}
167175c9cae5f85c72cbb1649e93849e16ede3f07522Chris Lattner
16721e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas GregorObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C,
16731e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                               unsigned ID) {
16746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr,
16756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                          SourceLocation(), SourceLocation(),
16766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                          SourceLocation());
16771e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor}
16781e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
16790d69b8cc8e90a9364771837cb42d7031b4cbb984Steve NaroffObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
1680ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek  // The class interface might be NULL if we are working with invalid code.
1681ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek  if (const ObjCInterfaceDecl *ID = getClassInterface())
1682ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek    return ID->FindCategoryDeclaration(getIdentifier());
16836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
16844292073a858f72769fa405b48390620c8932f8aeArgyrios Kyrtzidis}
16854292073a858f72769fa405b48390620c8932f8aeArgyrios Kyrtzidis
1686f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner
168799ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid ObjCImplDecl::anchor() { }
168899ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
168917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidisvoid ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
16902c2d43c557beca1b4ba4bd743f33978aecb46a97Douglas Gregor  // FIXME: The context should be correct before we get here.
1691653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor  property->setLexicalDeclContext(this);
169217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  addDecl(property);
1693653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor}
1694653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor
16958a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidisvoid ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
16968a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  ASTContext &Ctx = getASTContext();
16978a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
16988a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  if (ObjCImplementationDecl *ImplD
169998f2cca4b2731b5d43da7c1582dd443ecead658dDuncan Sands        = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
17008a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis    if (IFace)
17018a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis      Ctx.setObjCImplementation(IFace, ImplD);
17028a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
170398f2cca4b2731b5d43da7c1582dd443ecead658dDuncan Sands  } else if (ObjCCategoryImplDecl *ImplD =
17048a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis             dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
17058a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis    if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
17068a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis      Ctx.setObjCImplementation(CD, ImplD);
17078a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  }
17088a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
17098a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  ClassInterface = IFace;
17108a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis}
17118a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
1712ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
17136d1cb5c62671b0ab4d9c023addf80562d7a45fd1Fariborz Jahanian/// properties implemented in this \@implementation block and returns
1714ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner/// the implemented property that uses it.
1715aaa63a761c6671a08e3f4f463435b72739fa194bFariborz Jahanian///
17163aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris LattnerObjCPropertyImplDecl *ObjCImplDecl::
171717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios KyrtzidisFindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
1718651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *PID : property_impls())
1719ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    if (PID->getPropertyIvarDecl() &&
1720ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner        PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
1721ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner      return PID;
17226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
17230701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff}
17240701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff
1725ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
17261c3a46aa5a55068c3107e659333ccf10f6dab843James Dennett/// added to the list of those properties \@synthesized/\@dynamic in this
17271c3a46aa5a55068c3107e659333ccf10f6dab843James Dennett/// category \@implementation block.
1728559c0c4bbecc017aab0716d546c4fefbcc194687Fariborz Jahanian///
17293aa1861bd8b5121e53379b1a00f9d6ad8dead4f6Chris LattnerObjCPropertyImplDecl *ObjCImplDecl::
173017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios KyrtzidisFindPropertyImplDecl(IdentifierInfo *Id) const {
1731651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *PID : property_impls())
1732ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner    if (PID->getPropertyDecl()->getIdentifier() == Id)
1733ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner      return PID;
17346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
1735559c0c4bbecc017aab0716d546c4fefbcc194687Fariborz Jahanian}
1736559c0c4bbecc017aab0716d546c4fefbcc194687Fariborz Jahanian
17375f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerraw_ostream &clang::operator<<(raw_ostream &OS,
1738f978059b82db8c0d849c5f992036210b5ca53200Benjamin Kramer                               const ObjCCategoryImplDecl &CID) {
1739f978059b82db8c0d849c5f992036210b5ca53200Benjamin Kramer  OS << CID.getName();
1740900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer  return OS;
1741900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer}
1742900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer
1743ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
1744ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner// ObjCImplementationDecl
1745ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
17461e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner
174799ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid ObjCImplementationDecl::anchor() { }
174899ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
1749ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris LattnerObjCImplementationDecl *
17501eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
1751ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner                               ObjCInterfaceDecl *ClassInterface,
17521711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                               ObjCInterfaceDecl *SuperDecl,
17531711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis                               SourceLocation nameLoc,
1754af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                               SourceLocation atStartLoc,
1755634c5634817b9ad384a706fe87ab302985566bbaArgyrios Kyrtzidis                               SourceLocation superLoc,
1756af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                               SourceLocation IvarLBraceLoc,
1757af300298ab86752fa64e339ba34195888a830756Fariborz Jahanian                               SourceLocation IvarRBraceLoc) {
1758712ef874534ee1bef41d1aa4664ae36148ec8b12Fariborz Jahanian  if (ClassInterface && ClassInterface->hasDefinition())
1759712ef874534ee1bef41d1aa4664ae36148ec8b12Fariborz Jahanian    ClassInterface = ClassInterface->getDefinition();
1760651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return new (C, DC) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
1761651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                            nameLoc, atStartLoc, superLoc,
1762651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                            IvarLBraceLoc, IvarRBraceLoc);
1763ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner}
17641e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner
17651e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas GregorObjCImplementationDecl *
17661e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas GregorObjCImplementationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
17676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr,
17686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                            SourceLocation(), SourceLocation());
17691e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor}
17701e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
1771da6d976b0f2470bb3f854913bc3af3245845ad60John McCallvoid ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
1772da6d976b0f2470bb3f854913bc3af3245845ad60John McCall                                             CXXCtorInitializer ** initializers,
1773da6d976b0f2470bb3f854913bc3af3245845ad60John McCall                                                 unsigned numInitializers) {
1774da6d976b0f2470bb3f854913bc3af3245845ad60John McCall  if (numInitializers > 0) {
1775da6d976b0f2470bb3f854913bc3af3245845ad60John McCall    NumIvarInitializers = numInitializers;
1776da6d976b0f2470bb3f854913bc3af3245845ad60John McCall    CXXCtorInitializer **ivarInitializers =
1777da6d976b0f2470bb3f854913bc3af3245845ad60John McCall    new (C) CXXCtorInitializer*[NumIvarInitializers];
1778da6d976b0f2470bb3f854913bc3af3245845ad60John McCall    memcpy(ivarInitializers, initializers,
1779da6d976b0f2470bb3f854913bc3af3245845ad60John McCall           numInitializers * sizeof(CXXCtorInitializer*));
1780da6d976b0f2470bb3f854913bc3af3245845ad60John McCall    IvarInitializers = ivarInitializers;
1781da6d976b0f2470bb3f854913bc3af3245845ad60John McCall  }
1782da6d976b0f2470bb3f854913bc3af3245845ad60John McCall}
1783da6d976b0f2470bb3f854913bc3af3245845ad60John McCall
17845f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerraw_ostream &clang::operator<<(raw_ostream &OS,
1785f978059b82db8c0d849c5f992036210b5ca53200Benjamin Kramer                               const ObjCImplementationDecl &ID) {
1786f978059b82db8c0d849c5f992036210b5ca53200Benjamin Kramer  OS << ID.getName();
1787900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer  return OS;
1788900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer}
1789900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer
1790ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
1791ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner// ObjCCompatibleAliasDecl
1792ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
17931e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner
179499ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid ObjCCompatibleAliasDecl::anchor() { }
179599ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
1796ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris LattnerObjCCompatibleAliasDecl *
1797ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris LattnerObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
1798ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner                                SourceLocation L,
17991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                IdentifierInfo *Id,
1800ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner                                ObjCInterfaceDecl* AliasedClass) {
1801651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return new (C, DC) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
18021e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner}
18031e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner
18041e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas GregorObjCCompatibleAliasDecl *
18051e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas GregorObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
18066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(),
18076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                             nullptr, nullptr);
18081e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor}
18091e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
1810ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
1811ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner// ObjCPropertyDecl
1812ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
18131e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner
181499ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid ObjCPropertyDecl::anchor() { }
181599ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
1816ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris LattnerObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
1817ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner                                           SourceLocation L,
1818ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner                                           IdentifierInfo *Id,
1819d0502407c1b41b2ace326f355d7b7a6876246223Fariborz Jahanian                                           SourceLocation AtLoc,
182077bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian                                           SourceLocation LParenLoc,
182183a230c83a54190366138c1a4f4310ef838b88fcJohn McCall                                           TypeSourceInfo *T,
1822ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner                                           PropertyControl propControl) {
1823651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return new (C, DC) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T);
18241e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner}
18251e03a561f4bd96910cb31a8af53a6ad321a12b51Chris Lattner
1826651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C,
18271e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                       unsigned ID) {
18286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr,
18296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                      SourceLocation(), SourceLocation(),
18306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                      nullptr);
18311e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor}
18321e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
1833ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
1834ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner// ObjCPropertyImplDecl
1835ab35163a5b80bf1bd49f0eebb708970f2b0e04e9Chris Lattner//===----------------------------------------------------------------------===//
1836f4af5154571e0c5eadb19df10e65464766ef6683Chris Lattner
1837628b96f34e93b643b6e15e75eabb8d96079a7e27Fariborz JahanianObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
1838d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor                                                   DeclContext *DC,
1839628b96f34e93b643b6e15e75eabb8d96079a7e27Fariborz Jahanian                                                   SourceLocation atLoc,
1840628b96f34e93b643b6e15e75eabb8d96079a7e27Fariborz Jahanian                                                   SourceLocation L,
1841628b96f34e93b643b6e15e75eabb8d96079a7e27Fariborz Jahanian                                                   ObjCPropertyDecl *property,
18429f0afd4e79601d9982072ff9318e6f9a982c770eDaniel Dunbar                                                   Kind PK,
1843a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor                                                   ObjCIvarDecl *ivar,
1844a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor                                                   SourceLocation ivarLoc) {
1845651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return new (C, DC) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
1846651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                          ivarLoc);
1847628b96f34e93b643b6e15e75eabb8d96079a7e27Fariborz Jahanian}
1848f4af5154571e0c5eadb19df10e65464766ef6683Chris Lattner
1849651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C,
18501e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                               unsigned ID) {
18516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(),
18526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                          SourceLocation(), nullptr, Dynamic,
18536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                          nullptr, SourceLocation());
18541e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor}
18551e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
1856a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas GregorSourceRange ObjCPropertyImplDecl::getSourceRange() const {
1857a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor  SourceLocation EndLoc = getLocation();
1858a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor  if (IvarLoc.isValid())
1859a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor    EndLoc = IvarLoc;
18600ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner
1861a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor  return SourceRange(AtLoc, EndLoc);
1862a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor}
1863