14d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner//===--- SemaDeclObjC.cpp - Semantic Analysis for ObjC Declarations -------===//
24d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner//
34d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner//                     The LLVM Compiler Infrastructure
44d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
74d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner//
84d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner//===----------------------------------------------------------------------===//
94d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner//
104d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner//  This file implements semantic analysis for Objective C declarations.
114d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner//
124d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner//===----------------------------------------------------------------------===//
134d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
142d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h"
15f85e193739c953358c865005855253af4f68a497John McCall#include "clang/AST/ASTConsumer.h"
164d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner#include "clang/AST/ASTContext.h"
171a43415b28e60e0e421ef60e254126acec7ab462Argyrios Kyrtzidis#include "clang/AST/ASTMutationListener.h"
18651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/AST/DataRecursiveASTVisitor.h"
1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/DeclObjC.h"
2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/Expr.h"
2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/ExprObjC.h"
22f85e193739c953358c865005855253af4f68a497John McCall#include "clang/Basic/SourceManager.h"
2355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/DeclSpec.h"
2455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/ExternalSemaSource.h"
2555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/Lookup.h"
2655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/Scope.h"
2755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/ScopeInfo.h"
2850df6ae41f232612e5e88b19e0db9900d08d2f6cJohn McCall#include "llvm/ADT/DenseSet.h"
2950df6ae41f232612e5e88b19e0db9900d08d2f6cJohn McCall
304d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattnerusing namespace clang;
314d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
32f85e193739c953358c865005855253af4f68a497John McCall/// Check whether the given method, which must be in the 'init'
33f85e193739c953358c865005855253af4f68a497John McCall/// family, is a valid member of that family.
34f85e193739c953358c865005855253af4f68a497John McCall///
35f85e193739c953358c865005855253af4f68a497John McCall/// \param receiverTypeIfCall - if null, check this as if declaring it;
36f85e193739c953358c865005855253af4f68a497John McCall///   if non-null, check this as if making a call to it with the given
37f85e193739c953358c865005855253af4f68a497John McCall///   receiver type
38f85e193739c953358c865005855253af4f68a497John McCall///
39f85e193739c953358c865005855253af4f68a497John McCall/// \return true to indicate that there was an error and appropriate
40f85e193739c953358c865005855253af4f68a497John McCall///   actions were taken
41f85e193739c953358c865005855253af4f68a497John McCallbool Sema::checkInitMethod(ObjCMethodDecl *method,
42f85e193739c953358c865005855253af4f68a497John McCall                           QualType receiverTypeIfCall) {
43f85e193739c953358c865005855253af4f68a497John McCall  if (method->isInvalidDecl()) return true;
44f85e193739c953358c865005855253af4f68a497John McCall
45f85e193739c953358c865005855253af4f68a497John McCall  // This castAs is safe: methods that don't return an object
46f85e193739c953358c865005855253af4f68a497John McCall  // pointer won't be inferred as inits and will reject an explicit
47f85e193739c953358c865005855253af4f68a497John McCall  // objc_method_family(init).
48f85e193739c953358c865005855253af4f68a497John McCall
49f85e193739c953358c865005855253af4f68a497John McCall  // We ignore protocols here.  Should we?  What about Class?
50f85e193739c953358c865005855253af4f68a497John McCall
51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const ObjCObjectType *result =
52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      method->getReturnType()->castAs<ObjCObjectPointerType>()->getObjectType();
53f85e193739c953358c865005855253af4f68a497John McCall
54f85e193739c953358c865005855253af4f68a497John McCall  if (result->isObjCId()) {
55f85e193739c953358c865005855253af4f68a497John McCall    return false;
56f85e193739c953358c865005855253af4f68a497John McCall  } else if (result->isObjCClass()) {
57f85e193739c953358c865005855253af4f68a497John McCall    // fall through: always an error
58f85e193739c953358c865005855253af4f68a497John McCall  } else {
59f85e193739c953358c865005855253af4f68a497John McCall    ObjCInterfaceDecl *resultClass = result->getInterface();
60f85e193739c953358c865005855253af4f68a497John McCall    assert(resultClass && "unexpected object type!");
61f85e193739c953358c865005855253af4f68a497John McCall
62f85e193739c953358c865005855253af4f68a497John McCall    // It's okay for the result type to still be a forward declaration
63f85e193739c953358c865005855253af4f68a497John McCall    // if we're checking an interface declaration.
647723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor    if (!resultClass->hasDefinition()) {
65f85e193739c953358c865005855253af4f68a497John McCall      if (receiverTypeIfCall.isNull() &&
66f85e193739c953358c865005855253af4f68a497John McCall          !isa<ObjCImplementationDecl>(method->getDeclContext()))
67f85e193739c953358c865005855253af4f68a497John McCall        return false;
68f85e193739c953358c865005855253af4f68a497John McCall
69f85e193739c953358c865005855253af4f68a497John McCall    // Otherwise, we try to compare class types.
70f85e193739c953358c865005855253af4f68a497John McCall    } else {
71f85e193739c953358c865005855253af4f68a497John McCall      // If this method was declared in a protocol, we can't check
72f85e193739c953358c865005855253af4f68a497John McCall      // anything unless we have a receiver type that's an interface.
736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      const ObjCInterfaceDecl *receiverClass = nullptr;
74f85e193739c953358c865005855253af4f68a497John McCall      if (isa<ObjCProtocolDecl>(method->getDeclContext())) {
75f85e193739c953358c865005855253af4f68a497John McCall        if (receiverTypeIfCall.isNull())
76f85e193739c953358c865005855253af4f68a497John McCall          return false;
77f85e193739c953358c865005855253af4f68a497John McCall
78f85e193739c953358c865005855253af4f68a497John McCall        receiverClass = receiverTypeIfCall->castAs<ObjCObjectPointerType>()
79f85e193739c953358c865005855253af4f68a497John McCall          ->getInterfaceDecl();
80f85e193739c953358c865005855253af4f68a497John McCall
81f85e193739c953358c865005855253af4f68a497John McCall        // This can be null for calls to e.g. id<Foo>.
82f85e193739c953358c865005855253af4f68a497John McCall        if (!receiverClass) return false;
83f85e193739c953358c865005855253af4f68a497John McCall      } else {
84f85e193739c953358c865005855253af4f68a497John McCall        receiverClass = method->getClassInterface();
85f85e193739c953358c865005855253af4f68a497John McCall        assert(receiverClass && "method not associated with a class!");
86f85e193739c953358c865005855253af4f68a497John McCall      }
87f85e193739c953358c865005855253af4f68a497John McCall
88f85e193739c953358c865005855253af4f68a497John McCall      // If either class is a subclass of the other, it's fine.
89f85e193739c953358c865005855253af4f68a497John McCall      if (receiverClass->isSuperClassOf(resultClass) ||
90f85e193739c953358c865005855253af4f68a497John McCall          resultClass->isSuperClassOf(receiverClass))
91f85e193739c953358c865005855253af4f68a497John McCall        return false;
92f85e193739c953358c865005855253af4f68a497John McCall    }
93f85e193739c953358c865005855253af4f68a497John McCall  }
94f85e193739c953358c865005855253af4f68a497John McCall
95f85e193739c953358c865005855253af4f68a497John McCall  SourceLocation loc = method->getLocation();
96f85e193739c953358c865005855253af4f68a497John McCall
97f85e193739c953358c865005855253af4f68a497John McCall  // If we're in a system header, and this is not a call, just make
98f85e193739c953358c865005855253af4f68a497John McCall  // the method unusable.
99f85e193739c953358c865005855253af4f68a497John McCall  if (receiverTypeIfCall.isNull() && getSourceManager().isInSystemHeader(loc)) {
100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    method->addAttr(UnavailableAttr::CreateImplicit(Context,
101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                "init method returns a type unrelated to its receiver type",
102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                loc));
103f85e193739c953358c865005855253af4f68a497John McCall    return true;
104f85e193739c953358c865005855253af4f68a497John McCall  }
105f85e193739c953358c865005855253af4f68a497John McCall
106f85e193739c953358c865005855253af4f68a497John McCall  // Otherwise, it's an error.
107f85e193739c953358c865005855253af4f68a497John McCall  Diag(loc, diag::err_arc_init_method_unrelated_result_type);
108f85e193739c953358c865005855253af4f68a497John McCall  method->setInvalidDecl();
109f85e193739c953358c865005855253af4f68a497John McCall  return true;
110f85e193739c953358c865005855253af4f68a497John McCall}
111f85e193739c953358c865005855253af4f68a497John McCall
1123240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanianvoid Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod,
113f4d918fdf7da64215db8abe63945798c66e6d132Douglas Gregor                                   const ObjCMethodDecl *Overridden) {
114926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  if (Overridden->hasRelatedResultType() &&
115926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      !NewMethod->hasRelatedResultType()) {
116926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    // This can only happen when the method follows a naming convention that
117926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    // implies a related result type, and the original (overridden) method has
118926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    // a suitable return type, but the new (overriding) method does not have
119926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    // a suitable return type.
120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    QualType ResultType = NewMethod->getReturnType();
121176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    SourceRange ResultTypeRange = NewMethod->getReturnTypeSourceRange();
122926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
123926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    // Figure out which class this method is part of, if any.
124926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    ObjCInterfaceDecl *CurrentClass
125926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      = dyn_cast<ObjCInterfaceDecl>(NewMethod->getDeclContext());
126926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    if (!CurrentClass) {
127926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      DeclContext *DC = NewMethod->getDeclContext();
128926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(DC))
129926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor        CurrentClass = Cat->getClassInterface();
130926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      else if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(DC))
131926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor        CurrentClass = Impl->getClassInterface();
132926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      else if (ObjCCategoryImplDecl *CatImpl
133926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor               = dyn_cast<ObjCCategoryImplDecl>(DC))
134926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor        CurrentClass = CatImpl->getClassInterface();
135926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    }
136926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
137926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    if (CurrentClass) {
138926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      Diag(NewMethod->getLocation(),
139926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor           diag::warn_related_result_type_compatibility_class)
140926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor        << Context.getObjCInterfaceType(CurrentClass)
141926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor        << ResultType
142926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor        << ResultTypeRange;
143926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    } else {
144926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      Diag(NewMethod->getLocation(),
145926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor           diag::warn_related_result_type_compatibility_protocol)
146926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor        << ResultType
147926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor        << ResultTypeRange;
148926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    }
149926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
150e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor    if (ObjCMethodFamily Family = Overridden->getMethodFamily())
151e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor      Diag(Overridden->getLocation(),
1527cca821e1acf0f1b4fe892c3111bfb2086832e4eJohn McCall           diag::note_related_result_type_family)
1537cca821e1acf0f1b4fe892c3111bfb2086832e4eJohn McCall        << /*overridden method*/ 0
154e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor        << Family;
155e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor    else
156e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor      Diag(Overridden->getLocation(),
157e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor           diag::note_related_result_type_overridden);
158926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  }
1594e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().ObjCAutoRefCount) {
1603240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian    if ((NewMethod->hasAttr<NSReturnsRetainedAttr>() !=
1613240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian         Overridden->hasAttr<NSReturnsRetainedAttr>())) {
1623240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian        Diag(NewMethod->getLocation(),
1633240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian             diag::err_nsreturns_retained_attribute_mismatch) << 1;
1643240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian        Diag(Overridden->getLocation(), diag::note_previous_decl)
1653240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian        << "method";
1663240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian    }
1673240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian    if ((NewMethod->hasAttr<NSReturnsNotRetainedAttr>() !=
1683240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian              Overridden->hasAttr<NSReturnsNotRetainedAttr>())) {
1693240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian        Diag(NewMethod->getLocation(),
1703240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian             diag::err_nsreturns_retained_attribute_mismatch) << 0;
1713240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian        Diag(Overridden->getLocation(), diag::note_previous_decl)
1723240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian        << "method";
1733240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian    }
1740a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor    ObjCMethodDecl::param_const_iterator oi = Overridden->param_begin(),
1750a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor                                         oe = Overridden->param_end();
176491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    for (ObjCMethodDecl::param_iterator
177491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis           ni = NewMethod->param_begin(), ne = NewMethod->param_end();
1780a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor         ni != ne && oi != oe; ++ni, ++oi) {
179491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis      const ParmVarDecl *oldDecl = (*oi);
1803240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian      ParmVarDecl *newDecl = (*ni);
1813240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian      if (newDecl->hasAttr<NSConsumedAttr>() !=
1823240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian          oldDecl->hasAttr<NSConsumedAttr>()) {
1833240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian        Diag(newDecl->getLocation(),
1843240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian             diag::err_nsconsumed_attribute_mismatch);
1853240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian        Diag(oldDecl->getLocation(), diag::note_previous_decl)
1863240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian          << "parameter";
1873240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian      }
1883240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian    }
1893240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian  }
190926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor}
191926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
192f85e193739c953358c865005855253af4f68a497John McCall/// \brief Check a method declaration for compatibility with the Objective-C
193f85e193739c953358c865005855253af4f68a497John McCall/// ARC conventions.
194b846381fc3099b2340ba8c74d16178203a60d9a0John McCallbool Sema::CheckARCMethodDecl(ObjCMethodDecl *method) {
195f85e193739c953358c865005855253af4f68a497John McCall  ObjCMethodFamily family = method->getMethodFamily();
196f85e193739c953358c865005855253af4f68a497John McCall  switch (family) {
197f85e193739c953358c865005855253af4f68a497John McCall  case OMF_None:
19880cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber  case OMF_finalize:
199f85e193739c953358c865005855253af4f68a497John McCall  case OMF_retain:
200f85e193739c953358c865005855253af4f68a497John McCall  case OMF_release:
201f85e193739c953358c865005855253af4f68a497John McCall  case OMF_autorelease:
202f85e193739c953358c865005855253af4f68a497John McCall  case OMF_retainCount:
203f85e193739c953358c865005855253af4f68a497John McCall  case OMF_self:
204176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  case OMF_initialize:
2056c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  case OMF_performSelector:
206f85e193739c953358c865005855253af4f68a497John McCall    return false;
207f85e193739c953358c865005855253af4f68a497John McCall
2081b0a13e91088f6818016464ffb23616ced820cbcFariborz Jahanian  case OMF_dealloc:
209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (!Context.hasSameType(method->getReturnType(), Context.VoidTy)) {
210176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      SourceRange ResultTypeRange = method->getReturnTypeSourceRange();
2111b0a13e91088f6818016464ffb23616ced820cbcFariborz Jahanian      if (ResultTypeRange.isInvalid())
212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        Diag(method->getLocation(), diag::error_dealloc_bad_result_type)
213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            << method->getReturnType()
214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            << FixItHint::CreateInsertion(method->getSelectorLoc(0), "(void)");
2151b0a13e91088f6818016464ffb23616ced820cbcFariborz Jahanian      else
216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        Diag(method->getLocation(), diag::error_dealloc_bad_result_type)
217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            << method->getReturnType()
218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            << FixItHint::CreateReplacement(ResultTypeRange, "void");
2191b0a13e91088f6818016464ffb23616ced820cbcFariborz Jahanian      return true;
2201b0a13e91088f6818016464ffb23616ced820cbcFariborz Jahanian    }
2211b0a13e91088f6818016464ffb23616ced820cbcFariborz Jahanian    return false;
2221b0a13e91088f6818016464ffb23616ced820cbcFariborz Jahanian
223f85e193739c953358c865005855253af4f68a497John McCall  case OMF_init:
224f85e193739c953358c865005855253af4f68a497John McCall    // If the method doesn't obey the init rules, don't bother annotating it.
225b846381fc3099b2340ba8c74d16178203a60d9a0John McCall    if (checkInitMethod(method, QualType()))
226f85e193739c953358c865005855253af4f68a497John McCall      return true;
227f85e193739c953358c865005855253af4f68a497John McCall
228651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    method->addAttr(NSConsumesSelfAttr::CreateImplicit(Context));
229f85e193739c953358c865005855253af4f68a497John McCall
230f85e193739c953358c865005855253af4f68a497John McCall    // Don't add a second copy of this attribute, but otherwise don't
231f85e193739c953358c865005855253af4f68a497John McCall    // let it be suppressed.
232f85e193739c953358c865005855253af4f68a497John McCall    if (method->hasAttr<NSReturnsRetainedAttr>())
233f85e193739c953358c865005855253af4f68a497John McCall      return false;
234f85e193739c953358c865005855253af4f68a497John McCall    break;
235f85e193739c953358c865005855253af4f68a497John McCall
236f85e193739c953358c865005855253af4f68a497John McCall  case OMF_alloc:
237f85e193739c953358c865005855253af4f68a497John McCall  case OMF_copy:
238f85e193739c953358c865005855253af4f68a497John McCall  case OMF_mutableCopy:
239f85e193739c953358c865005855253af4f68a497John McCall  case OMF_new:
240f85e193739c953358c865005855253af4f68a497John McCall    if (method->hasAttr<NSReturnsRetainedAttr>() ||
241f85e193739c953358c865005855253af4f68a497John McCall        method->hasAttr<NSReturnsNotRetainedAttr>() ||
242f85e193739c953358c865005855253af4f68a497John McCall        method->hasAttr<NSReturnsAutoreleasedAttr>())
243f85e193739c953358c865005855253af4f68a497John McCall      return false;
244f85e193739c953358c865005855253af4f68a497John McCall    break;
245f85e193739c953358c865005855253af4f68a497John McCall  }
246f85e193739c953358c865005855253af4f68a497John McCall
247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  method->addAttr(NSReturnsRetainedAttr::CreateImplicit(Context));
248f85e193739c953358c865005855253af4f68a497John McCall  return false;
249f85e193739c953358c865005855253af4f68a497John McCall}
250f85e193739c953358c865005855253af4f68a497John McCall
2515ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanianstatic void DiagnoseObjCImplementedDeprecations(Sema &S,
2525ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian                                                NamedDecl *ND,
2535ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian                                                SourceLocation ImplLoc,
2545ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian                                                int select) {
2550a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  if (ND && ND->isDeprecated()) {
25698d810ee83d4c4bf5d89bbb43829533b84b20ecfFariborz Jahanian    S.Diag(ImplLoc, diag::warn_deprecated_def) << select;
2575ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian    if (select == 0)
2583306ec1923973d7b5767b23ba95915af2fec87d7Ted Kremenek      S.Diag(ND->getLocation(), diag::note_method_declared_at)
2593306ec1923973d7b5767b23ba95915af2fec87d7Ted Kremenek        << ND->getDeclName();
2605ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian    else
2615ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian      S.Diag(ND->getLocation(), diag::note_previous_decl) << "class";
2625ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian  }
2635ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian}
2645ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian
265140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian/// AddAnyMethodToGlobalPool - Add any method, instance or factory to global
266140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian/// pool.
267140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanianvoid Sema::AddAnyMethodToGlobalPool(Decl *D) {
268140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian  ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
269140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian
270140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian  // If we don't have a valid method decl, simply return.
271140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian  if (!MDecl)
272140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian    return;
273140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian  if (MDecl->isInstanceMethod())
274140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian    AddInstanceMethodToGlobalPool(MDecl, true);
275140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian  else
276140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian    AddFactoryMethodToGlobalPool(MDecl, true);
277140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian}
278140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian
279a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian/// HasExplicitOwnershipAttr - returns true when pointer to ObjC pointer
280a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian/// has explicit ownership attribute; false otherwise.
281a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanianstatic bool
282a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz JahanianHasExplicitOwnershipAttr(Sema &S, ParmVarDecl *Param) {
283a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian  QualType T = Param->getType();
284a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian
285a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian  if (const PointerType *PT = T->getAs<PointerType>()) {
286a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian    T = PT->getPointeeType();
287a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian  } else if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
288a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian    T = RT->getPointeeType();
289a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian  } else {
290a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian    return true;
291a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian  }
292a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian
293a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian  // If we have a lifetime qualifier, but it's local, we must have
294a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian  // inferred it. So, it is implicit.
295a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian  return !T.getLocalQualifiers().hasObjCLifetime();
296a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian}
297a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian
2988c6cb462946b8be19167fad7ff21d4f9fbaebfefFariborz Jahanian/// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
2998c6cb462946b8be19167fad7ff21d4f9fbaebfefFariborz Jahanian/// and user declared, in the method definition's AST.
3008c6cb462946b8be19167fad7ff21d4f9fbaebfefFariborz Jahanianvoid Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
3016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  assert((getCurMethodDecl() == nullptr) && "Methodparsing confused");
302d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
3036c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian
304394f3f483fa4e7b472630cfcd03f7840520958c5Steve Naroff  // If we don't have a valid method decl, simply return.
305394f3f483fa4e7b472630cfcd03f7840520958c5Steve Naroff  if (!MDecl)
306394f3f483fa4e7b472630cfcd03f7840520958c5Steve Naroff    return;
307a56f616744b929aa7115034e7e2f9a0b8df545f6Steve Naroff
3084d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // Allow all of Sema to see that we are entering a method definition.
30944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  PushDeclContext(FnBodyScope, MDecl);
3109ea9bdbc14374f7bacdb50d3e52c664ff12150ffDouglas Gregor  PushFunctionScope();
3119ea9bdbc14374f7bacdb50d3e52c664ff12150ffDouglas Gregor
3124d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // Create Decl objects for each parameter, entrring them in the scope for
3134d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // binding to their use.
3144d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
3154d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // Insert the invisible arguments, self and _cmd!
316fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanian  MDecl->createImplicitParams(Context, MDecl->getClassInterface());
3171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
318451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  PushOnScopeChains(MDecl->getSelfDecl(), FnBodyScope);
319451318c08a6342c10b8986060386fd9274418437Daniel Dunbar  PushOnScopeChains(MDecl->getCmdDecl(), FnBodyScope);
32004421087832a031c90bd58f128c7c0e741db8dd2Chris Lattner
3218c0501c7370d894a735692b92fab62bbb05d86bdReid Kleckner  // The ObjC parser requires parameter names so there's no need to check.
3228c0501c7370d894a735692b92fab62bbb05d86bdReid Kleckner  CheckParmsForFunctionDef(MDecl->param_begin(), MDecl->param_end(),
3238c0501c7370d894a735692b92fab62bbb05d86bdReid Kleckner                           /*CheckParameterNames=*/false);
3248c0501c7370d894a735692b92fab62bbb05d86bdReid Kleckner
3258123a95c33b792d35c2e4992ba6e27882748fb0dChris Lattner  // Introduce all of the other parameters into this scope.
326651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *Param : MDecl->params()) {
32723c0104bb8ad04f06804bd399cbc1f5f962b356cFariborz Jahanian    if (!Param->isInvalidDecl() &&
328a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian        getLangOpts().ObjCAutoRefCount &&
329a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian        !HasExplicitOwnershipAttr(*this, Param))
330a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian      Diag(Param->getLocation(), diag::warn_arc_strong_pointer_objc_pointer) <<
331a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian            Param->getType();
332918546c584c91ee917c919c967d7d73cecd295dcFariborz Jahanian
333651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (Param->getIdentifier())
334651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      PushOnScopeChains(Param, FnBodyScope);
33523c0104bb8ad04f06804bd399cbc1f5f962b356cFariborz Jahanian  }
336f85e193739c953358c865005855253af4f68a497John McCall
337f85e193739c953358c865005855253af4f68a497John McCall  // In ARC, disallow definition of retain/release/autorelease/retainCount
3384e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().ObjCAutoRefCount) {
339f85e193739c953358c865005855253af4f68a497John McCall    switch (MDecl->getMethodFamily()) {
340f85e193739c953358c865005855253af4f68a497John McCall    case OMF_retain:
341f85e193739c953358c865005855253af4f68a497John McCall    case OMF_retainCount:
342f85e193739c953358c865005855253af4f68a497John McCall    case OMF_release:
343f85e193739c953358c865005855253af4f68a497John McCall    case OMF_autorelease:
344f85e193739c953358c865005855253af4f68a497John McCall      Diag(MDecl->getLocation(), diag::err_arc_illegal_method_def)
345b8ed071b88c1fd100eaa701f5fd7f5ebe8b9e362Fariborz Jahanian        << 0 << MDecl->getSelector();
346f85e193739c953358c865005855253af4f68a497John McCall      break;
347f85e193739c953358c865005855253af4f68a497John McCall
348f85e193739c953358c865005855253af4f68a497John McCall    case OMF_None:
349f85e193739c953358c865005855253af4f68a497John McCall    case OMF_dealloc:
35080cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber    case OMF_finalize:
351f85e193739c953358c865005855253af4f68a497John McCall    case OMF_alloc:
352f85e193739c953358c865005855253af4f68a497John McCall    case OMF_init:
353f85e193739c953358c865005855253af4f68a497John McCall    case OMF_mutableCopy:
354f85e193739c953358c865005855253af4f68a497John McCall    case OMF_copy:
355f85e193739c953358c865005855253af4f68a497John McCall    case OMF_new:
356f85e193739c953358c865005855253af4f68a497John McCall    case OMF_self:
357176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    case OMF_initialize:
3589670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian    case OMF_performSelector:
359f85e193739c953358c865005855253af4f68a497John McCall      break;
360f85e193739c953358c865005855253af4f68a497John McCall    }
361f85e193739c953358c865005855253af4f68a497John McCall  }
362f85e193739c953358c865005855253af4f68a497John McCall
3639a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber  // Warn on deprecated methods under -Wdeprecated-implementations,
3649a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber  // and prepare for warning on missing super calls.
3659a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber  if (ObjCInterfaceDecl *IC = MDecl->getClassInterface()) {
366841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian    ObjCMethodDecl *IMD =
367841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian      IC->lookupMethod(MDecl->getSelector(), MDecl->isInstanceMethod());
368841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian
3695fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian    if (IMD) {
3705fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian      ObjCImplDecl *ImplDeclOfMethodDef =
3715fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian        dyn_cast<ObjCImplDecl>(MDecl->getDeclContext());
3725fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian      ObjCContainerDecl *ContDeclOfMethodDecl =
3735fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian        dyn_cast<ObjCContainerDecl>(IMD->getDeclContext());
3746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      ObjCImplDecl *ImplDeclOfMethodDecl = nullptr;
3755fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian      if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ContDeclOfMethodDecl))
3765fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian        ImplDeclOfMethodDecl = OID->getImplementation();
377651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(ContDeclOfMethodDecl)) {
378651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (CD->IsClassExtension()) {
379651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          if (ObjCInterfaceDecl *OID = CD->getClassInterface())
380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            ImplDeclOfMethodDecl = OID->getImplementation();
381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        } else
382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            ImplDeclOfMethodDecl = CD->getImplementation();
383651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      }
3845fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian      // No need to issue deprecated warning if deprecated mehod in class/category
3855fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian      // is being implemented in its own implementation (no overriding is involved).
3865fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian      if (!ImplDeclOfMethodDecl || ImplDeclOfMethodDecl != ImplDeclOfMethodDef)
3875fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian        DiagnoseObjCImplementedDeprecations(*this,
3885ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian                                          dyn_cast<NamedDecl>(IMD),
3895ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian                                          MDecl->getLocation(), 0);
3905fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian    }
3919a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber
392651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (MDecl->getMethodFamily() == OMF_init) {
393651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (MDecl->isDesignatedInitializerForTheInterface()) {
394651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        getCurFunction()->ObjCIsDesignatedInit = true;
395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        getCurFunction()->ObjCWarnForNoDesignatedInitChain =
3966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines            IC->getSuperClass() != nullptr;
397651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      } else if (IC->hasDesignatedInitializers()) {
398651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        getCurFunction()->ObjCIsSecondaryInit = true;
399651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        getCurFunction()->ObjCWarnForNoInitDelegation = true;
400651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      }
401651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
402651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
40380cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber    // If this is "dealloc" or "finalize", set some bit here.
4049a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber    // Then in ActOnSuperMessage() (SemaExprObjC), set it back to false.
4059a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber    // Finally, in ActOnFinishFunctionBody() (SemaDecl), warn if flag is set.
4069a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber    // Only do this if the current class actually has a superclass.
40741f3f3a4792f46787632fdb94f952f6b3ce3f4aeJordan Rose    if (const ObjCInterfaceDecl *SuperClass = IC->getSuperClass()) {
408535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose      ObjCMethodFamily Family = MDecl->getMethodFamily();
409535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose      if (Family == OMF_dealloc) {
410535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose        if (!(getLangOpts().ObjCAutoRefCount ||
411535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose              getLangOpts().getGC() == LangOptions::GCOnly))
412535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose          getCurFunction()->ObjCShouldCallSuper = true;
413535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose
414535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose      } else if (Family == OMF_finalize) {
415535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose        if (Context.getLangOpts().getGC() != LangOptions::NonGC)
416535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose          getCurFunction()->ObjCShouldCallSuper = true;
417535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose
4182b61039ceb9162e7b47ed4cb92b957c8a7668da1Fariborz Jahanian      } else {
419535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose        const ObjCMethodDecl *SuperMethod =
42041f3f3a4792f46787632fdb94f952f6b3ce3f4aeJordan Rose          SuperClass->lookupMethod(MDecl->getSelector(),
42141f3f3a4792f46787632fdb94f952f6b3ce3f4aeJordan Rose                                   MDecl->isInstanceMethod());
422535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose        getCurFunction()->ObjCShouldCallSuper =
423535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose          (SuperMethod && SuperMethod->hasAttr<ObjCRequiresSuperAttr>());
4246f9386049c6dee2df33a4b7a6dfeda2733acce7dFariborz Jahanian      }
42580cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber    }
4269a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber  }
4274d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
4284d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
4292f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrainnamespace {
4302f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain
4312f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain// Callback to only accept typo corrections that are Objective-C classes.
4322f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain// If an ObjCInterfaceDecl* is given to the constructor, then the validation
4332f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain// function will reject corrections to that class.
4342f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrainclass ObjCInterfaceValidatorCCC : public CorrectionCandidateCallback {
4352f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain public:
4366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCInterfaceValidatorCCC() : CurrentIDecl(nullptr) {}
4372f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain  explicit ObjCInterfaceValidatorCCC(ObjCInterfaceDecl *IDecl)
4382f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain      : CurrentIDecl(IDecl) {}
4392f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain
440651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool ValidateCandidate(const TypoCorrection &candidate) override {
4412f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain    ObjCInterfaceDecl *ID = candidate.getCorrectionDeclAs<ObjCInterfaceDecl>();
4422f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain    return ID && !declaresSameEntity(ID, CurrentIDecl);
4432f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain  }
4442f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain
4452f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain private:
4462f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain  ObjCInterfaceDecl *CurrentIDecl;
4472f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain};
4482f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain
4492f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain}
4502f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain
451d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema::
4527caeabd868d46cf4e68478c6e9136dae4e735d21Chris LattnerActOnStartClassInterface(SourceLocation AtInterfaceLoc,
4537caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner                         IdentifierInfo *ClassName, SourceLocation ClassLoc,
4547caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner                         IdentifierInfo *SuperName, SourceLocation SuperLoc,
455d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall                         Decl * const *ProtoRefs, unsigned NumProtoRefs,
45618df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor                         const SourceLocation *ProtoLocs,
4577caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner                         SourceLocation EndProtoLoc, AttributeList *AttrList) {
4584d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  assert(ClassName && "Missing class identifier");
4591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4604d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // Check for another declaration kind with the same name.
461c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, ClassLoc,
462c0b39640de335809ca7544f802751112619f30ccDouglas Gregor                                         LookupOrdinaryName, ForRedeclaration);
46372c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor
464a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
4653c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
4665f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner    Diag(PrevDecl->getLocation(), diag::note_previous_definition);
4674d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
4681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4697723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor  // Create a declaration to describe this @interface.
4700af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor  ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
471e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis
472e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis  if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) {
473e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis    // A previous decl with a different name is because of
474e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis    // @compatibility_alias, for example:
475e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis    // \code
476e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis    //   @class NewImage;
477e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis    //   @compatibility_alias OldImage NewImage;
478e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis    // \endcode
479e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis    // A lookup for 'OldImage' will return the 'NewImage' decl.
480e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis    //
481e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis    // In such a case use the real declaration name, instead of the alias one,
482e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis    // otherwise we will break IdentifierResolver and redecls-chain invariants.
483e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis    // FIXME: If necessary, add a bit to indicate that this ObjCInterfaceDecl
484e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis    // has been aliased.
485e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis    ClassName = PrevIDecl->getIdentifier();
486e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis  }
487e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis
4887723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor  ObjCInterfaceDecl *IDecl
4897723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor    = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName,
4900af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor                                PrevIDecl, ClassLoc);
4917723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor
4927723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor  if (PrevIDecl) {
4937723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor    // Class already seen. Was it a definition?
4947723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor    if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) {
4957723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor      Diag(AtInterfaceLoc, diag::err_duplicate_class_def)
4967723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor        << PrevIDecl->getDeclName();
4972e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor      Diag(Def->getLocation(), diag::note_previous_definition);
4987723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor      IDecl->setInvalidDecl();
4994d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    }
500deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor  }
5017723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor
5027723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor  if (AttrList)
5037723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor    ProcessDeclAttributeList(TUScope, IDecl, AttrList);
5047723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor  PushOnScopeChains(IDecl, TUScope);
50574c730ad1f6818b676b0bad46d806a9176950328Sebastian Redl
5067723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor  // Start the definition of this class. If we're in a redefinition case, there
5077723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor  // may already be a definition, so we'll end up adding to it.
5082e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor  if (!IDecl->hasDefinition())
5092e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    IDecl->startDefinition();
5102e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
5114d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  if (SuperName) {
5124d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    // Check if a different kind of symbol declared in this scope.
513c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor    PrevDecl = LookupSingleName(TUScope, SuperName, SuperLoc,
514c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor                                LookupOrdinaryName);
515f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor
516f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor    if (!PrevDecl) {
5172f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain      // Try to correct for a typo in the superclass name without correcting
5182f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain      // to the class we're defining.
519176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      if (TypoCorrection Corrected =
520176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines              CorrectTypo(DeclarationNameInfo(SuperName, SuperLoc),
521176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          LookupOrdinaryName, TUScope, nullptr,
522176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          llvm::make_unique<ObjCInterfaceValidatorCCC>(IDecl),
523176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                          CTK_ErrorRecovery)) {
5242d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith        diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest)
5252d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith                                    << SuperName << ClassName);
5262f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain        PrevDecl = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>();
527f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor      }
528f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor    }
529f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor
53060ef308e51c71b760d7f598c1b763ceb7b768148Douglas Gregor    if (declaresSameEntity(PrevDecl, IDecl)) {
531fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian      Diag(SuperLoc, diag::err_recursive_superclass)
532fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian        << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
53305c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor      IDecl->setEndOfDefinitionLoc(ClassLoc);
534ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
5351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      ObjCInterfaceDecl *SuperClassDecl =
536fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian                                dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
5373c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner
538fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian      // Diagnose classes that inherit from deprecated classes.
539fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian      if (SuperClassDecl)
540fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian        (void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc);
5411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (PrevDecl && !SuperClassDecl) {
543fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian        // The previous declaration was not a class decl. Check if we have a
544fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian        // typedef. If we do, get the underlying class type.
545162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        if (const TypedefNameDecl *TDecl =
546162e1c1b487352434552147967c3dd296ebee2f7Richard Smith              dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) {
547fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian          QualType T = TDecl->getUnderlyingType();
548c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall          if (T->isObjCObjectType()) {
549740991bdf8bb2638ff111ae2084791c52c1cee00Fariborz Jahanian            if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface()) {
550deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor              SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
551740991bdf8bb2638ff111ae2084791c52c1cee00Fariborz Jahanian              // This handles the following case:
552740991bdf8bb2638ff111ae2084791c52c1cee00Fariborz Jahanian              // @interface NewI @end
553740991bdf8bb2638ff111ae2084791c52c1cee00Fariborz Jahanian              // typedef NewI DeprI __attribute__((deprecated("blah")))
554740991bdf8bb2638ff111ae2084791c52c1cee00Fariborz Jahanian              // @interface SI : DeprI /* warn here */ @end
555740991bdf8bb2638ff111ae2084791c52c1cee00Fariborz Jahanian              (void)DiagnoseUseOfDecl(const_cast<TypedefNameDecl*>(TDecl), SuperLoc);
556740991bdf8bb2638ff111ae2084791c52c1cee00Fariborz Jahanian            }
557fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian          }
558818cb9eaba6279675af8c3b87c464d21d3796682Steve Naroff        }
5591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
560fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian        // This handles the following case:
561fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian        //
562fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian        // typedef int SuperClass;
563fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian        // @interface MyClass : SuperClass {} @end
564fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian        //
565fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian        if (!SuperClassDecl) {
566fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian          Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
567fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian          Diag(PrevDecl->getLocation(), diag::note_previous_definition);
568fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian        }
569818cb9eaba6279675af8c3b87c464d21d3796682Steve Naroff      }
5701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
571162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      if (!dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) {
572fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian        if (!SuperClassDecl)
573fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian          Diag(SuperLoc, diag::err_undef_superclass)
574fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian            << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
575b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor        else if (RequireCompleteType(SuperLoc,
576d10099e5c8238fa0327f03921cf2e3c8975c881eDouglas Gregor                                  Context.getObjCInterfaceType(SuperClassDecl),
577d10099e5c8238fa0327f03921cf2e3c8975c881eDouglas Gregor                                     diag::err_forward_superclass,
578d10099e5c8238fa0327f03921cf2e3c8975c881eDouglas Gregor                                     SuperClassDecl->getDeclName(),
579d10099e5c8238fa0327f03921cf2e3c8975c881eDouglas Gregor                                     ClassName,
580d10099e5c8238fa0327f03921cf2e3c8975c881eDouglas Gregor                                     SourceRange(AtInterfaceLoc, ClassLoc))) {
5816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          SuperClassDecl = nullptr;
582a81397323cc8475ef8243f938118a9c231fb18ffFariborz Jahanian        }
583fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian      }
584fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian      IDecl->setSuperClass(SuperClassDecl);
585fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian      IDecl->setSuperClassLoc(SuperLoc);
58605c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor      IDecl->setEndOfDefinitionLoc(SuperLoc);
587818cb9eaba6279675af8c3b87c464d21d3796682Steve Naroff    }
5884d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  } else { // we have a root class.
58905c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor    IDecl->setEndOfDefinitionLoc(ClassLoc);
5904d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
5911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5920b17c61e8f143901ce11b4a6e5129ac63aaeee04Sebastian Redl  // Check then save referenced protocols.
59306036d3709955a53297b4cbe14e20db88f321470Chris Lattner  if (NumProtoRefs) {
59431ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky    IDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs,
59518df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor                           ProtoLocs, Context);
59605c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor    IDecl->setEndOfDefinitionLoc(EndProtoLoc);
5974d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
5981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
59915281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson  CheckObjCDeclScope(IDecl);
6003a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  return ActOnObjCContainerStartDefinition(IDecl);
6014d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
6024d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
603a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian/// ActOnTypedefedProtocols - this action finds protocol list as part of the
604a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian/// typedef'ed use for a qualified super class and adds them to the list
605a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian/// of the protocols.
606a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanianvoid Sema::ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs,
607a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian                                   IdentifierInfo *SuperName,
608a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian                                   SourceLocation SuperLoc) {
609a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian  if (!SuperName)
610a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian    return;
611a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian  NamedDecl* IDecl = LookupSingleName(TUScope, SuperName, SuperLoc,
612a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian                                      LookupOrdinaryName);
613a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian  if (!IDecl)
614a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian    return;
615a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian
616a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian  if (const TypedefNameDecl *TDecl = dyn_cast_or_null<TypedefNameDecl>(IDecl)) {
617a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian    QualType T = TDecl->getUnderlyingType();
618a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian    if (T->isObjCObjectType())
619a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian      if (const ObjCObjectType *OPT = T->getAs<ObjCObjectType>())
6200e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        ProtocolRefs.append(OPT->qual_begin(), OPT->qual_end());
621a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian  }
622a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian}
623a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian
624de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith/// ActOnCompatibilityAlias - this action is called after complete parsing of
6251dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// a \@compatibility_alias declaration. It sets up the alias relationships.
626de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard SmithDecl *Sema::ActOnCompatibilityAlias(SourceLocation AtLoc,
627de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith                                    IdentifierInfo *AliasName,
628de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith                                    SourceLocation AliasLocation,
629de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith                                    IdentifierInfo *ClassName,
630de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith                                    SourceLocation ClassLocation) {
6314d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // Look for previous declaration of alias name
632c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, AliasLocation,
633c0b39640de335809ca7544f802751112619f30ccDouglas Gregor                                      LookupOrdinaryName, ForRedeclaration);
6344d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  if (ADecl) {
635104f96ba1a59026d6a71b4ef39ca127b56324e4aEli Friedman    Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName;
6368b265bd5eba1394273693e6705a43adac6b6aa2fChris Lattner    Diag(ADecl->getLocation(), diag::note_previous_declaration);
6376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
6384d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
6394d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // Check for class declaration
640c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
641c0b39640de335809ca7544f802751112619f30ccDouglas Gregor                                       LookupOrdinaryName, ForRedeclaration);
642162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (const TypedefNameDecl *TDecl =
643162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        dyn_cast_or_null<TypedefNameDecl>(CDeclU)) {
644305c658ebce84bb9833fc0e7675554656453b8e8Fariborz Jahanian    QualType T = TDecl->getUnderlyingType();
645c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall    if (T->isObjCObjectType()) {
646c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall      if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface()) {
647305c658ebce84bb9833fc0e7675554656453b8e8Fariborz Jahanian        ClassName = IDecl->getIdentifier();
648c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor        CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
649c0b39640de335809ca7544f802751112619f30ccDouglas Gregor                                  LookupOrdinaryName, ForRedeclaration);
650305c658ebce84bb9833fc0e7675554656453b8e8Fariborz Jahanian      }
651305c658ebce84bb9833fc0e7675554656453b8e8Fariborz Jahanian    }
652305c658ebce84bb9833fc0e7675554656453b8e8Fariborz Jahanian  }
653f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner  ObjCInterfaceDecl *CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDeclU);
6546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!CDecl) {
6553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    Diag(ClassLocation, diag::warn_undef_interface) << ClassName;
656f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner    if (CDeclU)
6578b265bd5eba1394273693e6705a43adac6b6aa2fChris Lattner      Diag(CDeclU->getLocation(), diag::note_previous_declaration);
6586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
6594d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
6601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
661f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner  // Everything checked out, instantiate a new alias declaration AST.
6621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ObjCCompatibleAliasDecl *AliasDecl =
663d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor    ObjCCompatibleAliasDecl::Create(Context, CurContext, AtLoc, AliasName, CDecl);
6641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
66515281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson  if (!CheckObjCDeclScope(AliasDecl))
666516ff43cc4e20b637335d3dfa5b197ca8faa09cbDouglas Gregor    PushOnScopeChains(AliasDecl, TUScope);
667d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor
668d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  return AliasDecl;
6694d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
6704d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
671819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanianbool Sema::CheckForwardProtocolDeclarationForCircularDependency(
67261d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff  IdentifierInfo *PName,
67361d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff  SourceLocation &Ploc, SourceLocation PrevLoc,
674819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian  const ObjCList<ObjCProtocolDecl> &PList) {
675819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian
676819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian  bool res = false;
67761d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff  for (ObjCList<ObjCProtocolDecl>::iterator I = PList.begin(),
67861d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff       E = PList.end(); I != E; ++I) {
679c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor    if (ObjCProtocolDecl *PDecl = LookupProtocol((*I)->getIdentifier(),
680c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor                                                 Ploc)) {
68161d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff      if (PDecl->getIdentifier() == PName) {
68261d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff        Diag(Ploc, diag::err_protocol_has_circular_dependency);
68361d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff        Diag(PrevLoc, diag::note_previous_definition);
684819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian        res = true;
68561d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff      }
6865e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor
6875e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor      if (!PDecl->hasDefinition())
6885e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor        continue;
6895e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor
690819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian      if (CheckForwardProtocolDeclarationForCircularDependency(PName, Ploc,
691819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian            PDecl->getLocation(), PDecl->getReferencedProtocols()))
692819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian        res = true;
69361d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff    }
69461d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff  }
695819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian  return res;
69661d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff}
69761d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff
698d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *
699e13b9595dc1e2f4288bec34f3412359f648e84a5Chris LattnerSema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
700e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner                                  IdentifierInfo *ProtocolName,
701e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner                                  SourceLocation ProtocolLoc,
702d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall                                  Decl * const *ProtoRefs,
703e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner                                  unsigned NumProtoRefs,
70418df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor                                  const SourceLocation *ProtoLocs,
705246e70f69cb8aeb67225c54690f1c6b25abd5a86Daniel Dunbar                                  SourceLocation EndProtoLoc,
706246e70f69cb8aeb67225c54690f1c6b25abd5a86Daniel Dunbar                                  AttributeList *AttrList) {
70796b69a7305e20c98f1a3e2e7cd52e2d6c5d53835Fariborz Jahanian  bool err = false;
708246e70f69cb8aeb67225c54690f1c6b25abd5a86Daniel Dunbar  // FIXME: Deal with AttrList.
7094d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  assert(ProtocolName && "Missing protocol identifier");
71027c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor  ObjCProtocolDecl *PrevDecl = LookupProtocol(ProtocolName, ProtocolLoc,
71127c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor                                              ForRedeclaration);
7126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCProtocolDecl *PDecl = nullptr;
7136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (ObjCProtocolDecl *Def = PrevDecl? PrevDecl->getDefinition() : nullptr) {
71427c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    // If we already have a definition, complain.
71527c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName;
71627c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    Diag(Def->getLocation(), diag::note_previous_definition);
71727c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor
71827c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    // Create a new protocol that is completely distinct from previous
71927c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    // declarations, and do not make this protocol available for name lookup.
72027c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    // That way, we'll end up completely ignoring the duplicate.
72127c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    // FIXME: Can we turn this into an error?
72227c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName,
72327c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor                                     ProtocolLoc, AtProtoInterfaceLoc,
7246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                     /*PrevDecl=*/nullptr);
72527c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    PDecl->startDefinition();
72627c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor  } else {
72727c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    if (PrevDecl) {
72827c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor      // Check for circular dependencies among protocol declarations. This can
72927c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor      // only happen if this protocol was forward-declared.
7304fc04da71ed46d63dc991dbea4fd52341e56c0a1Argyrios Kyrtzidis      ObjCList<ObjCProtocolDecl> PList;
7314fc04da71ed46d63dc991dbea4fd52341e56c0a1Argyrios Kyrtzidis      PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context);
7324fc04da71ed46d63dc991dbea4fd52341e56c0a1Argyrios Kyrtzidis      err = CheckForwardProtocolDeclarationForCircularDependency(
73327c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor              ProtocolName, ProtocolLoc, PrevDecl->getLocation(), PList);
7344d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    }
73527c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor
73627c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    // Create the new declaration.
7371711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis    PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName,
738b05d7b20171bbd2feb14b059f39332cbe1bf1014Argyrios Kyrtzidis                                     ProtocolLoc, AtProtoInterfaceLoc,
739c9d3c7edb513e9b8a6ab65b04133653e71d7a72bDouglas Gregor                                     /*PrevDecl=*/PrevDecl);
74027c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor
7416e378de1aebdfeb44f2a7677ed207b32b3a41fbfDouglas Gregor    PushOnScopeChains(PDecl, TUScope);
7425e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    PDecl->startDefinition();
743cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner  }
7445e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor
745bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  if (AttrList)
7469cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttributeList(TUScope, PDecl, AttrList);
74727c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor
74827c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor  // Merge attributes from previous declarations.
74927c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor  if (PrevDecl)
75027c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    mergeDeclAttributes(PDecl, PrevDecl);
75127c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor
75296b69a7305e20c98f1a3e2e7cd52e2d6c5d53835Fariborz Jahanian  if (!err && NumProtoRefs ) {
753c858105d41602a2dadb2efbc1af80a7b791ebac3Chris Lattner    /// Check then save referenced protocols.
75431ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky    PDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs,
75518df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor                           ProtoLocs, Context);
7564d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
7571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  CheckObjCDeclScope(PDecl);
7593a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  return ActOnObjCContainerStartDefinition(PDecl);
7604d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
7614d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
762651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic bool NestedProtocolHasNoDefinition(ObjCProtocolDecl *PDecl,
763651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                          ObjCProtocolDecl *&UndefinedProtocol) {
764651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!PDecl->hasDefinition() || PDecl->getDefinition()->isHidden()) {
765651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    UndefinedProtocol = PDecl;
766651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return true;
767651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
768651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
769651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *PI : PDecl->protocols())
770651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (NestedProtocolHasNoDefinition(PI, UndefinedProtocol)) {
771651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      UndefinedProtocol = PI;
772651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return true;
773651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
774651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return false;
775651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
776651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
7774d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// FindProtocolDeclaration - This routine looks up protocols and
7787ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar/// issues an error if they are not declared. It returns list of
7797ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar/// protocol declarations in its 'Protocols' argument.
7804d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattnervoid
781e13b9595dc1e2f4288bec34f3412359f648e84a5Chris LattnerSema::FindProtocolDeclaration(bool WarnOnDeclarations,
7827caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner                              const IdentifierLocPair *ProtocolId,
7834d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner                              unsigned NumProtocols,
7845f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                              SmallVectorImpl<Decl *> &Protocols) {
7854d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  for (unsigned i = 0; i != NumProtocols; ++i) {
786c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor    ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolId[i].first,
787c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor                                             ProtocolId[i].second);
788eacc39212e5960b2680067c006384c2e4804873aChris Lattner    if (!PDecl) {
789d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor      TypoCorrection Corrected = CorrectTypo(
790d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor          DeclarationNameInfo(ProtocolId[i].first, ProtocolId[i].second),
791176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          LookupObjCProtocolName, TUScope, nullptr,
792176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          llvm::make_unique<DeclFilterCCC<ObjCProtocolDecl>>(),
7936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          CTK_ErrorRecovery);
7942d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith      if ((PDecl = Corrected.getCorrectionDeclAs<ObjCProtocolDecl>()))
7952d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith        diagnoseTypo(Corrected, PDiag(diag::err_undeclared_protocol_suggest)
7962d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith                                    << ProtocolId[i].first);
797f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor    }
798f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor
799f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor    if (!PDecl) {
800fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      Diag(ProtocolId[i].second, diag::err_undeclared_protocol)
8013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << ProtocolId[i].first;
802eacc39212e5960b2680067c006384c2e4804873aChris Lattner      continue;
803eacc39212e5960b2680067c006384c2e4804873aChris Lattner    }
8043c9a0240b6db6ee02a24f48c753089bda48843aeFariborz Jahanian    // If this is a forward protocol declaration, get its definition.
8053c9a0240b6db6ee02a24f48c753089bda48843aeFariborz Jahanian    if (!PDecl->isThisDeclarationADefinition() && PDecl->getDefinition())
8063c9a0240b6db6ee02a24f48c753089bda48843aeFariborz Jahanian      PDecl = PDecl->getDefinition();
8073c9a0240b6db6ee02a24f48c753089bda48843aeFariborz Jahanian
80848f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor    (void)DiagnoseUseOfDecl(PDecl, ProtocolId[i].second);
809eacc39212e5960b2680067c006384c2e4804873aChris Lattner
810eacc39212e5960b2680067c006384c2e4804873aChris Lattner    // If this is a forward declaration and we are supposed to warn in this
811eacc39212e5960b2680067c006384c2e4804873aChris Lattner    // case, do it.
8120f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor    // FIXME: Recover nicely in the hidden case.
813651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ObjCProtocolDecl *UndefinedProtocol;
814651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
8150f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor    if (WarnOnDeclarations &&
816651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        NestedProtocolHasNoDefinition(PDecl, UndefinedProtocol)) {
817fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      Diag(ProtocolId[i].second, diag::warn_undef_protocolref)
8183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << ProtocolId[i].first;
819651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Diag(UndefinedProtocol->getLocation(), diag::note_protocol_decl_undefined)
820651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        << UndefinedProtocol;
821651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
822d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    Protocols.push_back(PDecl);
8234d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
8244d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
8254d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
82678c39c76103a36e37a05b1e40da93850ea64647bFariborz Jahanian/// DiagnoseClassExtensionDupMethods - Check for duplicate declaration of
827b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian/// a class method in its extension.
828b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian///
8291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
830b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian                                            ObjCInterfaceDecl *ID) {
831b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian  if (!ID)
832b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian    return;  // Possibly due to previous error
833b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian
834b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian  llvm::DenseMap<Selector, const ObjCMethodDecl*> MethodMap;
835651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *MD : ID->methods())
836b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian    MethodMap[MD->getSelector()] = MD;
837b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian
838b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian  if (MethodMap.empty())
839b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian    return;
840651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *Method : CAT->methods()) {
841b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian    const ObjCMethodDecl *&PrevMethod = MethodMap[Method->getSelector()];
842651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (PrevMethod &&
843651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        (PrevMethod->isInstanceMethod() == Method->isInstanceMethod()) &&
844651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        !MatchTwoMethodDeclarations(Method, PrevMethod)) {
845b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian      Diag(Method->getLocation(), diag::err_duplicate_method_decl)
846b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian            << Method->getDeclName();
847b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian      Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
848b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian    }
849b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian  }
850b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian}
851b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian
8521dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// ActOnForwardProtocolDeclaration - Handle \@protocol foo;
853bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas GregorSema::DeclGroupPtrTy
8544d3914836e85258e9ace7306999413e3c7ea6c11Chris LattnerSema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
8557caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner                                      const IdentifierLocPair *IdentList,
856bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian                                      unsigned NumElts,
857bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian                                      AttributeList *attrList) {
858bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor  SmallVector<Decl *, 8> DeclsInGroup;
8594d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  for (unsigned i = 0; i != NumElts; ++i) {
8607caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner    IdentifierInfo *Ident = IdentList[i].first;
86127c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    ObjCProtocolDecl *PrevDecl = LookupProtocol(Ident, IdentList[i].second,
86227c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor                                                ForRedeclaration);
86327c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    ObjCProtocolDecl *PDecl
86427c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor      = ObjCProtocolDecl::Create(Context, CurContext, Ident,
86527c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor                                 IdentList[i].second, AtProtocolLoc,
866c9d3c7edb513e9b8a6ab65b04133653e71d7a72bDouglas Gregor                                 PrevDecl);
86727c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor
86827c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    PushOnScopeChains(PDecl, TUScope);
869bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor    CheckObjCDeclScope(PDecl);
87027c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor
8713937f87e53b3ee0c8da93536f48f6f96c006309dDouglas Gregor    if (attrList)
8729cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor      ProcessDeclAttributeList(TUScope, PDecl, attrList);
87327c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor
87427c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor    if (PrevDecl)
87527c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor      mergeDeclAttributes(PDecl, PrevDecl);
87627c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor
877bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor    DeclsInGroup.push_back(PDecl);
8784d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
8791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8804549d7ffc15bdd7ab860aa68db089d9f559b79e7Rafael Espindola  return BuildDeclaratorGroup(DeclsInGroup, false);
8814d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
8824d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
883d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema::
8847caeabd868d46cf4e68478c6e9136dae4e735d21Chris LattnerActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
8857caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner                            IdentifierInfo *ClassName, SourceLocation ClassLoc,
8867caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner                            IdentifierInfo *CategoryName,
8877caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner                            SourceLocation CategoryLoc,
888d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall                            Decl * const *ProtoRefs,
8897caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner                            unsigned NumProtoRefs,
89018df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor                            const SourceLocation *ProtoLocs,
8917caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner                            SourceLocation EndProtoLoc) {
89280aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian  ObjCCategoryDecl *CDecl;
893c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true);
89409b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek
89509b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek  /// Check that class of this category is already completely declared.
896b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor
897b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor  if (!IDecl
898b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor      || RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
899d10099e5c8238fa0327f03921cf2e3c8975c881eDouglas Gregor                             diag::err_category_forward_interface,
9006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                             CategoryName == nullptr)) {
90109b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek    // Create an invalid ObjCCategoryDecl to serve as context for
90209b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek    // the enclosing method declarations.  We mark the decl invalid
90309b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek    // to make it clear that this isn't a valid AST.
90409b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek    CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc,
905955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis                                     ClassLoc, CategoryLoc, CategoryName,IDecl);
90609b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek    CDecl->setInvalidDecl();
9079a0b6b4e2bf6a9ef41d32b4e83f2911981d2d44dArgyrios Kyrtzidis    CurContext->addDecl(CDecl);
908b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor
909b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor    if (!IDecl)
910b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor      Diag(ClassLoc, diag::err_undef_interface) << ClassName;
9113a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis    return ActOnObjCContainerStartDefinition(CDecl);
91209b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek  }
91309b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek
91480aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian  if (!CategoryName && IDecl->getImplementation()) {
91580aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian    Diag(ClassLoc, diag::err_class_extension_after_impl) << ClassName;
91680aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian    Diag(IDecl->getImplementation()->getLocation(),
91780aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian          diag::note_implementation_declared);
91809b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek  }
91909b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek
92025760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian  if (CategoryName) {
92125760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian    /// Check for duplicate interface declaration for this category
922d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    if (ObjCCategoryDecl *Previous
923d329724745b49f894b768d47275b7c2713106e89Douglas Gregor          = IDecl->FindCategoryDeclaration(CategoryName)) {
924d329724745b49f894b768d47275b7c2713106e89Douglas Gregor      // Class extensions can be declared multiple times, categories cannot.
925d329724745b49f894b768d47275b7c2713106e89Douglas Gregor      Diag(CategoryLoc, diag::warn_dup_category_def)
926d329724745b49f894b768d47275b7c2713106e89Douglas Gregor        << ClassName << CategoryName;
927d329724745b49f894b768d47275b7c2713106e89Douglas Gregor      Diag(Previous->getLocation(), diag::note_previous_definition);
9284d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    }
9297c453b3ded5dc9bff05e6e66eb725a0938303d73Fariborz Jahanian  }
9304d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
931955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis  CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc,
932955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis                                   ClassLoc, CategoryLoc, CategoryName, IDecl);
933955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis  // FIXME: PushOnScopeChains?
934955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis  CurContext->addDecl(CDecl);
935955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis
9364d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  if (NumProtoRefs) {
93731ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky    CDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs,
93818df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor                           ProtoLocs, Context);
939339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian    // Protocols in the class extension belong to the class.
94025760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian    if (CDecl->IsClassExtension())
94131ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky     IDecl->mergeClassExtensionProtocolList((ObjCProtocolDecl*const*)ProtoRefs,
94253b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek                                            NumProtoRefs, Context);
9434d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
9441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
94515281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson  CheckObjCDeclScope(CDecl);
9463a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  return ActOnObjCContainerStartDefinition(CDecl);
9474d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
9484d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
9494d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// ActOnStartCategoryImplementation - Perform semantic checks on the
950a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// category implementation declaration and build an ObjCCategoryImplDecl
9514d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// object.
952d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema::ActOnStartCategoryImplementation(
9534d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner                      SourceLocation AtCatImplLoc,
9544d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner                      IdentifierInfo *ClassName, SourceLocation ClassLoc,
9554d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner                      IdentifierInfo *CatName, SourceLocation CatLoc) {
956c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true);
9576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCCategoryDecl *CatIDecl = nullptr;
9585a61e0c4229dc82617a37a68ac2fc08d46e00488Argyrios Kyrtzidis  if (IDecl && IDecl->hasDefinition()) {
9598a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis    CatIDecl = IDecl->FindCategoryDeclaration(CatName);
9608a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis    if (!CatIDecl) {
9618a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis      // Category @implementation with no corresponding @interface.
9628a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis      // Create and install one.
96337f40572c4c78a8c57a7b45266f8b86db172a7c1Argyrios Kyrtzidis      CatIDecl = ObjCCategoryDecl::Create(Context, CurContext, AtCatImplLoc,
96437f40572c4c78a8c57a7b45266f8b86db172a7c1Argyrios Kyrtzidis                                          ClassLoc, CatLoc,
965955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis                                          CatName, IDecl);
96637f40572c4c78a8c57a7b45266f8b86db172a7c1Argyrios Kyrtzidis      CatIDecl->setImplicit();
9678a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis    }
9688a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  }
9698a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis
9701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ObjCCategoryImplDecl *CDecl =
9711711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis    ObjCCategoryImplDecl::Create(Context, CurContext, CatName, IDecl,
972c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis                                 ClassLoc, AtCatImplLoc, CatLoc);
9734d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  /// Check that class of this category is already completely declared.
974b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor  if (!IDecl) {
9753c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    Diag(ClassLoc, diag::err_undef_interface) << ClassName;
9766c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    CDecl->setInvalidDecl();
977b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor  } else if (RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
978b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor                                 diag::err_undef_interface)) {
979b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor    CDecl->setInvalidDecl();
9806c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  }
9814d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
982d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor  // FIXME: PushOnScopeChains?
98317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  CurContext->addDecl(CDecl);
984d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor
985c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis  // If the interface is deprecated/unavailable, warn/error about it.
986c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis  if (IDecl)
987c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis    DiagnoseUseOfDecl(IDecl, ClassLoc);
988c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis
9898a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  /// Check that CatName, category name, is not used in another implementation.
9908a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  if (CatIDecl) {
9918a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis    if (CatIDecl->getImplementation()) {
9928a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis      Diag(ClassLoc, diag::err_dup_implementation_category) << ClassName
9938a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis        << CatName;
9948a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis      Diag(CatIDecl->getImplementation()->getLocation(),
9958a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis           diag::note_previous_definition);
996df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis      CDecl->setInvalidDecl();
997b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian    } else {
9988a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis      CatIDecl->setImplementation(CDecl);
999b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian      // Warn on implementating category of deprecated class under
1000b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian      // -Wdeprecated-implementations flag.
10015ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian      DiagnoseObjCImplementedDeprecations(*this,
10025ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian                                          dyn_cast<NamedDecl>(IDecl),
10035ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian                                          CDecl->getLocation(), 2);
1004b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian    }
10058a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  }
10061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
100715281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson  CheckObjCDeclScope(CDecl);
10083a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  return ActOnObjCContainerStartDefinition(CDecl);
10094d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
10104d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
1011d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema::ActOnStartClassImplementation(
10124d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner                      SourceLocation AtClassImplLoc,
10134d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner                      IdentifierInfo *ClassName, SourceLocation ClassLoc,
10141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                      IdentifierInfo *SuperClassname,
10154d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner                      SourceLocation SuperClassLoc) {
10166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCInterfaceDecl *IDecl = nullptr;
10174d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // Check for another declaration kind with the same name.
1018f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall  NamedDecl *PrevDecl
1019c0b39640de335809ca7544f802751112619f30ccDouglas Gregor    = LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName,
1020c0b39640de335809ca7544f802751112619f30ccDouglas Gregor                       ForRedeclaration);
1021a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
10223c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
10235f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner    Diag(PrevDecl->getLocation(), diag::note_previous_definition);
1024deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor  } else if ((IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))) {
10250af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor    RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
10260af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor                        diag::warn_undef_interface);
102795ff742380d1c3dd5152739183bfe085cf27197fDouglas Gregor  } else {
10282d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith    // We did not find anything with the name ClassName; try to correct for
102995ff742380d1c3dd5152739183bfe085cf27197fDouglas Gregor    // typos in the class name.
1030176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    TypoCorrection Corrected = CorrectTypo(
1031176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        DeclarationNameInfo(ClassName, ClassLoc), LookupOrdinaryName, TUScope,
1032176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        nullptr, llvm::make_unique<ObjCInterfaceValidatorCCC>(), CTK_NonError);
10332d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith    if (Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) {
10342d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith      // Suggest the (potentially) correct interface name. Don't provide a
10352d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith      // code-modification hint or use the typo name for recovery, because
10362d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith      // this is just a warning. The program may actually be correct.
10372d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith      diagnoseTypo(Corrected,
10382d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith                   PDiag(diag::warn_undef_interface_suggest) << ClassName,
10392d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith                   /*ErrorRecovery*/false);
104095ff742380d1c3dd5152739183bfe085cf27197fDouglas Gregor    } else {
104195ff742380d1c3dd5152739183bfe085cf27197fDouglas Gregor      Diag(ClassLoc, diag::warn_undef_interface) << ClassName;
104295ff742380d1c3dd5152739183bfe085cf27197fDouglas Gregor    }
10434d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
10441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10454d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // Check that super class name is valid class name
10466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCInterfaceDecl *SDecl = nullptr;
10474d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  if (SuperClassname) {
10484d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    // Check if a different kind of symbol declared in this scope.
1049c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor    PrevDecl = LookupSingleName(TUScope, SuperClassname, SuperClassLoc,
1050c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor                                LookupOrdinaryName);
1051a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
10523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      Diag(SuperClassLoc, diag::err_redefinition_different_kind)
10533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << SuperClassname;
10545f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner      Diag(PrevDecl->getLocation(), diag::note_previous_definition);
10553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    } else {
10561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      SDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
1057cd707abbc758149d9f7d37bd0b25298455c678b2Argyrios Kyrtzidis      if (SDecl && !SDecl->hasDefinition())
10586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        SDecl = nullptr;
10594d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner      if (!SDecl)
10603c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        Diag(SuperClassLoc, diag::err_undef_superclass)
10613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner          << SuperClassname << ClassName;
106260ef308e51c71b760d7f598c1b763ceb7b768148Douglas Gregor      else if (IDecl && !declaresSameEntity(IDecl->getSuperClass(), SDecl)) {
10634d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner        // This implementation and its interface do not have the same
10644d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner        // super class.
10653c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        Diag(SuperClassLoc, diag::err_conflicting_super_class)
106608631c5fa053867146b5ee8be658c229f6bf127cChris Lattner          << SDecl->getDeclName();
10675f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner        Diag(SDecl->getLocation(), diag::note_previous_definition);
10684d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner      }
10694d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    }
10704d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
10711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10724d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  if (!IDecl) {
10734d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    // Legacy case of @implementation with no corresponding @interface.
10744d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    // Build, chain & install the interface decl into the identifier.
1075f6414927e67e27d9324d8d179c5f7ea620443924Daniel Dunbar
1076390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Do we support attributes on the @implementation? If so we should
1077390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // copy them over.
10781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
10796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                      ClassName, /*PrevDecl=*/nullptr, ClassLoc,
10800af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor                                      true);
10812e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    IDecl->startDefinition();
108205c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor    if (SDecl) {
108305c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor      IDecl->setSuperClass(SDecl);
108405c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor      IDecl->setSuperClassLoc(SuperClassLoc);
108505c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor      IDecl->setEndOfDefinitionLoc(SuperClassLoc);
108605c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor    } else {
108705c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor      IDecl->setEndOfDefinitionLoc(ClassLoc);
108805c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor    }
108905c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor
10908b9fb3082bc54cf7ffe6c3772500a73388f53072Douglas Gregor    PushOnScopeChains(IDecl, TUScope);
1091deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor  } else {
1092deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor    // Mark the interface as being completed, even if it was just as
1093deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor    //   @class ....;
1094deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor    // declaration; the user cannot reopen it.
10952e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (!IDecl->hasDefinition())
10962e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor      IDecl->startDefinition();
10974d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
10981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ObjCImplementationDecl* IMPDecl =
11001711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis    ObjCImplementationDecl::Create(Context, CurContext, IDecl, SDecl,
1101634c5634817b9ad384a706fe87ab302985566bbaArgyrios Kyrtzidis                                   ClassLoc, AtClassImplLoc, SuperClassLoc);
11021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
110315281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson  if (CheckObjCDeclScope(IMPDecl))
11043a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis    return ActOnObjCContainerStartDefinition(IMPDecl);
11051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11064d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // Check that there is no duplicate implementation of this class.
1107deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor  if (IDecl->getImplementation()) {
1108deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor    // FIXME: Don't leak everything!
11093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName;
111087018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis    Diag(IDecl->getImplementation()->getLocation(),
111187018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis         diag::note_previous_definition);
1112df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis    IMPDecl->setInvalidDecl();
1113deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor  } else { // add it to the list.
11148a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis    IDecl->setImplementation(IMPDecl);
11158fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor    PushOnScopeChains(IMPDecl, TUScope);
1116b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian    // Warn on implementating deprecated class under
1117b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian    // -Wdeprecated-implementations flag.
11185ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian    DiagnoseObjCImplementedDeprecations(*this,
11195ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian                                        dyn_cast<NamedDecl>(IDecl),
11205ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian                                        IMPDecl->getLocation(), 1);
11218a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis  }
11223a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  return ActOnObjCContainerStartDefinition(IMPDecl);
11234d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
11244d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
1125644af7b50bd0541468b45c197f5b637e934d48a0Argyrios KyrtzidisSema::DeclGroupPtrTy
1126644af7b50bd0541468b45c197f5b637e934d48a0Argyrios KyrtzidisSema::ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef<Decl *> Decls) {
1127644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis  SmallVector<Decl *, 64> DeclsInGroup;
1128644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis  DeclsInGroup.reserve(Decls.size() + 1);
1129644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis
1130644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis  for (unsigned i = 0, e = Decls.size(); i != e; ++i) {
1131644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis    Decl *Dcl = Decls[i];
1132644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis    if (!Dcl)
1133644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis      continue;
1134644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis    if (Dcl->getDeclContext()->isFileContext())
1135644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis      Dcl->setTopLevelDeclInObjCContainer();
1136644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis    DeclsInGroup.push_back(Dcl);
1137644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis  }
1138644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis
1139644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis  DeclsInGroup.push_back(ObjCImpDecl);
1140644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis
11414549d7ffc15bdd7ab860aa68db089d9f559b79e7Rafael Espindola  return BuildDeclaratorGroup(DeclsInGroup, false);
1142644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis}
1143644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis
1144a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekvoid Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
1145a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek                                    ObjCIvarDecl **ivars, unsigned numIvars,
11464d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner                                    SourceLocation RBrace) {
11474d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  assert(ImpDecl && "missing implementation decl");
11484afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  ObjCInterfaceDecl* IDecl = ImpDecl->getClassInterface();
11494d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  if (!IDecl)
11504d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    return;
11511dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett  /// Check case of non-existing \@interface decl.
11521dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett  /// (legacy objective-c \@implementation decl without an \@interface decl).
11534d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  /// Add implementations's ivar to the synthesize class's ivar list.
115433feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff  if (IDecl->isImplicitInterfaceDecl()) {
115505c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor    IDecl->setEndOfDefinitionLoc(RBrace);
11563a21cd92f425680fcbfbab9552c0787b09ae9ca7Fariborz Jahanian    // Add ivar's to class's DeclContext.
11573a21cd92f425680fcbfbab9552c0787b09ae9ca7Fariborz Jahanian    for (unsigned i = 0, e = numIvars; i != e; ++i) {
11582f14c4d18fcba4b4577dbe43016d6d42ef9973cfFariborz Jahanian      ivars[i]->setLexicalDeclContext(ImpDecl);
11591b7f9cbed1b96b58a6e5f7808ebc9345a76a0936Richard Smith      IDecl->makeDeclVisibleInContext(ivars[i]);
116011062e11236b7bc689dad150e8b490fd6b063ec3Fariborz Jahanian      ImpDecl->addDecl(ivars[i]);
11613a21cd92f425680fcbfbab9552c0787b09ae9ca7Fariborz Jahanian    }
11623a21cd92f425680fcbfbab9552c0787b09ae9ca7Fariborz Jahanian
11634d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    return;
11644d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
11654d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // If implementation has empty ivar list, just return.
11664d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  if (numIvars == 0)
11674d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    return;
11681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11694d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  assert(ivars && "missing @implementation ivars");
1170260611a32535c851237926bfcf78869b13c07d5bJohn McCall  if (LangOpts.ObjCRuntime.isNonFragile()) {
1171bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian    if (ImpDecl->getSuperClass())
1172bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian      Diag(ImpDecl->getLocation(), diag::warn_on_superclass_use);
1173bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian    for (unsigned i = 0; i < numIvars; i++) {
1174bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian      ObjCIvarDecl* ImplIvar = ivars[i];
1175bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian      if (const ObjCIvarDecl *ClsIvar =
1176bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian            IDecl->getIvarDecl(ImplIvar->getIdentifier())) {
1177bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian        Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration);
1178bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian        Diag(ClsIvar->getLocation(), diag::note_previous_definition);
1179bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian        continue;
1180bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian      }
11813b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian      // Check class extensions (unnamed categories) for duplicate ivars.
1182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      for (const auto *CDecl : IDecl->visible_extensions()) {
11833b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian        if (const ObjCIvarDecl *ClsExtIvar =
11843b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian            CDecl->getIvarDecl(ImplIvar->getIdentifier())) {
11853b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian          Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration);
11863b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian          Diag(ClsExtIvar->getLocation(), diag::note_previous_definition);
11873b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian          continue;
11883b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian        }
11893b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian      }
1190bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian      // Instance ivar to Implementation's DeclContext.
1191bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian      ImplIvar->setLexicalDeclContext(ImpDecl);
11921b7f9cbed1b96b58a6e5f7808ebc9345a76a0936Richard Smith      IDecl->makeDeclVisibleInContext(ImplIvar);
1193bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian      ImpDecl->addDecl(ImplIvar);
1194bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian    }
1195bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian    return;
1196bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian  }
11974d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // Check interface's Ivar list against those in the implementation.
11984d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // names and types must match.
11994d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  //
12004d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  unsigned j = 0;
12011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ObjCInterfaceDecl::ivar_iterator
12024c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner    IVI = IDecl->ivar_begin(), IVE = IDecl->ivar_end();
12034c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner  for (; numIvars > 0 && IVI != IVE; ++IVI) {
1204a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    ObjCIvarDecl* ImplIvar = ivars[j++];
1205581deb3da481053c4993c7600f97acf7768caac5David Blaikie    ObjCIvarDecl* ClsIvar = *IVI;
12064d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    assert (ImplIvar && "missing implementation ivar");
12074d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    assert (ClsIvar && "missing class ivar");
12081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1209ca33129bb28b05938c3e6c9f8a66165b5cceb4ddSteve Naroff    // First, make sure the types match.
1210a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith    if (!Context.hasSameType(ImplIvar->getType(), ClsIvar->getType())) {
1211fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type)
121208631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << ImplIvar->getIdentifier()
121308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << ImplIvar->getType() << ClsIvar->getType();
12145f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner      Diag(ClsIvar->getLocation(), diag::note_previous_definition);
1215a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith    } else if (ImplIvar->isBitField() && ClsIvar->isBitField() &&
1216a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith               ImplIvar->getBitWidthValue(Context) !=
1217a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith               ClsIvar->getBitWidthValue(Context)) {
1218a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith      Diag(ImplIvar->getBitWidth()->getLocStart(),
1219a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith           diag::err_conflicting_ivar_bitwidth) << ImplIvar->getIdentifier();
1220a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith      Diag(ClsIvar->getBitWidth()->getLocStart(),
1221a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith           diag::note_previous_definition);
12221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
1223ca33129bb28b05938c3e6c9f8a66165b5cceb4ddSteve Naroff    // Make sure the names are identical.
1224ca33129bb28b05938c3e6c9f8a66165b5cceb4ddSteve Naroff    if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) {
1225fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name)
122608631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << ImplIvar->getIdentifier() << ClsIvar->getIdentifier();
12275f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner      Diag(ClsIvar->getLocation(), diag::note_previous_definition);
12284d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    }
12294d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    --numIvars;
12304d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
12311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1232609e4c72d9190a57636836d658b3563d9a9545aeChris Lattner  if (numIvars > 0)
1233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Diag(ivars[j]->getLocation(), diag::err_inconsistent_ivar_count);
1234609e4c72d9190a57636836d658b3563d9a9545aeChris Lattner  else if (IVI != IVE)
1235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Diag(IVI->getLocation(), diag::err_inconsistent_ivar_count);
12364d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
12374d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
1238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void WarnUndefinedMethod(Sema &S, SourceLocation ImpLoc,
1239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                ObjCMethodDecl *method,
1240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                bool &IncompleteImpl,
1241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                unsigned DiagID,
12426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                NamedDecl *NeededFor = nullptr) {
1243327126ee3d2faad9314b2633974eefc672f73b79Fariborz Jahanian  // No point warning no definition of method which is 'unavailable'.
124486f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor  switch (method->getAvailability()) {
124586f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor  case AR_Available:
124686f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor  case AR_Deprecated:
124786f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor    break;
124886f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor
124986f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor      // Don't warn about unavailable or not-yet-introduced methods.
125086f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor  case AR_NotYetIntroduced:
125186f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor  case AR_Unavailable:
1252327126ee3d2faad9314b2633974eefc672f73b79Fariborz Jahanian    return;
125386f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor  }
125486f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor
12558b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek  // FIXME: For now ignore 'IncompleteImpl'.
12568b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek  // Previously we grouped all unimplemented methods under a single
12578b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek  // warning, but some users strongly voiced that they would prefer
12588b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek  // separate warnings.  We will give that approach a try, as that
12598b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek  // matches what we do with protocols.
1260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  {
1261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    const Sema::SemaDiagnosticBuilder &B = S.Diag(ImpLoc, DiagID);
1262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    B << method;
1263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (NeededFor)
1264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      B << NeededFor;
1265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
12668b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek
12678b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek  // Issue a note to the original declaration.
12688b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek  SourceLocation MethodLoc = method->getLocStart();
12698b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek  if (MethodLoc.isValid())
1270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    S.Diag(MethodLoc, diag::note_method_declared_at) << method;
12713c2eb66b0acb13c4bdd628e5e148c37958a85ec4Steve Naroff}
12723c2eb66b0acb13c4bdd628e5e148c37958a85ec4Steve Naroff
1273e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// Determines if type B can be substituted for type A.  Returns true if we can
1274e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// guarantee that anything that the user will do to an object of type A can
1275e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// also be done to an object of type B.  This is trivially true if the two
1276e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// types are the same, or if B is a subclass of A.  It becomes more complex
1277e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// in cases where protocols are involved.
1278e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall///
1279e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// Object types in Objective-C describe the minimum requirements for an
1280e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// object, rather than providing a complete description of a type.  For
1281e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// example, if A is a subclass of B, then B* may refer to an instance of A.
1282e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// The principle of substitutability means that we may use an instance of A
1283e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// anywhere that we may use an instance of B - it will implement all of the
1284e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// ivars of B and all of the methods of B.
1285e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall///
1286e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// This substitutability is important when type checking methods, because
1287e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// the implementation may have stricter type definitions than the interface.
1288e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// The interface specifies minimum requirements, but the implementation may
1289e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// have more accurate ones.  For example, a method may privately accept
1290e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// instances of B, but only publish that it accepts instances of A.  Any
1291e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// object passed to it will be type checked against B, and so will implicitly
1292e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// by a valid A*.  Similarly, a method may return a subclass of the class that
1293e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// it is declared as returning.
1294e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall///
1295e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// This is most important when considering subclassing.  A method in a
1296e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// subclass must accept any object as an argument that its superclass's
1297e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// implementation accepts.  It may, however, accept a more general type
1298e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// without breaking substitutability (i.e. you can still use the subclass
1299e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// anywhere that you can use the superclass, but not vice versa).  The
1300e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// converse requirement applies to return types: the return type for a
1301e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// subclass method must be a valid object of the kind that the superclass
1302e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// advertises, but it may be specified more accurately.  This avoids the need
1303e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// for explicit down-casting by callers.
1304e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall///
1305e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// Note: This is a stricter requirement than for assignment.
130610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCallstatic bool isObjCTypeSubstitutable(ASTContext &Context,
130710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall                                    const ObjCObjectPointerType *A,
130810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall                                    const ObjCObjectPointerType *B,
130910302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall                                    bool rejectId) {
131010302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  // Reject a protocol-unqualified id.
131110302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  if (rejectId && B->isObjCIdType()) return false;
1312e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall
1313e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall  // If B is a qualified id, then A must also be a qualified id and it must
1314e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall  // implement all of the protocols in B.  It may not be a qualified class.
1315e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall  // For example, MyClass<A> can be assigned to id<A>, but MyClass<A> is a
1316e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall  // stricter definition so it is not substitutable for id<A>.
1317e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall  if (B->isObjCQualifiedIdType()) {
1318e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall    return A->isObjCQualifiedIdType() &&
131910302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall           Context.ObjCQualifiedIdTypesAreCompatible(QualType(A, 0),
132010302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall                                                     QualType(B,0),
132110302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall                                                     false);
1322e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall  }
1323e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall
1324e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall  /*
1325e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall  // id is a special type that bypasses type checking completely.  We want a
1326e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall  // warning when it is used in one place but not another.
1327e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall  if (C.isObjCIdType(A) || C.isObjCIdType(B)) return false;
1328e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall
1329e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall
1330e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall  // If B is a qualified id, then A must also be a qualified id (which it isn't
1331e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall  // if we've got this far)
1332e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall  if (B->isObjCQualifiedIdType()) return false;
1333e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall  */
1334e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall
1335e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall  // Now we know that A and B are (potentially-qualified) class types.  The
1336e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall  // normal rules for assignment apply.
133710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  return Context.canAssignObjCInterfaces(A, B);
1338e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall}
1339e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall
134010302c01e8ceffd86c1a2b1bb15466e852ca8898John McCallstatic SourceRange getTypeRange(TypeSourceInfo *TSI) {
134110302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  return (TSI ? TSI->getTypeLoc().getSourceRange() : SourceRange());
134210302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall}
134310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall
1344fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanianstatic bool CheckMethodOverrideReturn(Sema &S,
134510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall                                      ObjCMethodDecl *MethodImpl,
134621761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian                                      ObjCMethodDecl *MethodDecl,
1347eee3ef177a171c06f826c331e7a9e256d01eaeb0Fariborz Jahanian                                      bool IsProtocolMethodDecl,
1348730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian                                      bool IsOverridingMode,
1349fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian                                      bool Warn) {
135021761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian  if (IsProtocolMethodDecl &&
135121761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian      (MethodDecl->getObjCDeclQualifier() !=
135221761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian       MethodImpl->getObjCDeclQualifier())) {
1353fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    if (Warn) {
1354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      S.Diag(MethodImpl->getLocation(),
1355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines             (IsOverridingMode
1356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                  ? diag::warn_conflicting_overriding_ret_type_modifiers
1357651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                  : diag::warn_conflicting_ret_type_modifiers))
1358730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian          << MethodImpl->getDeclName()
1359176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          << MethodImpl->getReturnTypeSourceRange();
1360651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration)
1361176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          << MethodDecl->getReturnTypeSourceRange();
1362fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    }
1363fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    else
1364fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian      return false;
136521761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian  }
1366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1367651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (S.Context.hasSameUnqualifiedType(MethodImpl->getReturnType(),
1368651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                       MethodDecl->getReturnType()))
1369fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    return true;
1370fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  if (!Warn)
1371fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    return false;
137210302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall
1373730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian  unsigned DiagID =
1374730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian    IsOverridingMode ? diag::warn_conflicting_overriding_ret_types
1375730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian                     : diag::warn_conflicting_ret_types;
137610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall
137710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  // Mismatches between ObjC pointers go into a different warning
137810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  // category, and sometimes they're even completely whitelisted.
137910302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  if (const ObjCObjectPointerType *ImplPtrTy =
1380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          MethodImpl->getReturnType()->getAs<ObjCObjectPointerType>()) {
138110302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall    if (const ObjCObjectPointerType *IfacePtrTy =
1382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            MethodDecl->getReturnType()->getAs<ObjCObjectPointerType>()) {
138310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall      // Allow non-matching return types as long as they don't violate
138410302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall      // the principle of substitutability.  Specifically, we permit
138510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall      // return types that are subclasses of the declared return type,
138610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall      // or that are more-qualified versions of the declared type.
138710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall      if (isObjCTypeSubstitutable(S.Context, IfacePtrTy, ImplPtrTy, false))
1388fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian        return false;
138910302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall
1390730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian      DiagID =
1391730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian        IsOverridingMode ? diag::warn_non_covariant_overriding_ret_types
1392730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian                          : diag::warn_non_covariant_ret_types;
139310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall    }
139410302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  }
139510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall
139610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  S.Diag(MethodImpl->getLocation(), DiagID)
1397651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      << MethodImpl->getDeclName() << MethodDecl->getReturnType()
1398651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      << MethodImpl->getReturnType()
1399176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      << MethodImpl->getReturnTypeSourceRange();
1400651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  S.Diag(MethodDecl->getLocation(), IsOverridingMode
1401651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                        ? diag::note_previous_declaration
1402651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                        : diag::note_previous_definition)
1403176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      << MethodDecl->getReturnTypeSourceRange();
1404fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  return false;
140510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall}
140610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall
1407fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanianstatic bool CheckMethodOverrideParam(Sema &S,
140810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall                                     ObjCMethodDecl *MethodImpl,
140921761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian                                     ObjCMethodDecl *MethodDecl,
141010302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall                                     ParmVarDecl *ImplVar,
141121761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian                                     ParmVarDecl *IfaceVar,
1412eee3ef177a171c06f826c331e7a9e256d01eaeb0Fariborz Jahanian                                     bool IsProtocolMethodDecl,
1413730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian                                     bool IsOverridingMode,
1414fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian                                     bool Warn) {
141521761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian  if (IsProtocolMethodDecl &&
141621761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian      (ImplVar->getObjCDeclQualifier() !=
141721761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian       IfaceVar->getObjCDeclQualifier())) {
1418fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    if (Warn) {
1419730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian      if (IsOverridingMode)
1420730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian        S.Diag(ImplVar->getLocation(),
1421730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian               diag::warn_conflicting_overriding_param_modifiers)
1422730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian            << getTypeRange(ImplVar->getTypeSourceInfo())
1423730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian            << MethodImpl->getDeclName();
1424730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian      else S.Diag(ImplVar->getLocation(),
1425fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian             diag::warn_conflicting_param_modifiers)
1426fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian          << getTypeRange(ImplVar->getTypeSourceInfo())
1427730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian          << MethodImpl->getDeclName();
1428fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian      S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration)
1429fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian          << getTypeRange(IfaceVar->getTypeSourceInfo());
1430fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    }
1431fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    else
1432fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian      return false;
143321761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian  }
143421761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian
143510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  QualType ImplTy = ImplVar->getType();
143610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  QualType IfaceTy = IfaceVar->getType();
143721761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian
143810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  if (S.Context.hasSameUnqualifiedType(ImplTy, IfaceTy))
1439fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    return true;
1440fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian
1441fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  if (!Warn)
1442fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    return false;
1443730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian  unsigned DiagID =
1444730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian    IsOverridingMode ? diag::warn_conflicting_overriding_param_types
1445730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian                     : diag::warn_conflicting_param_types;
144610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall
144710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  // Mismatches between ObjC pointers go into a different warning
144810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  // category, and sometimes they're even completely whitelisted.
144910302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  if (const ObjCObjectPointerType *ImplPtrTy =
145010302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall        ImplTy->getAs<ObjCObjectPointerType>()) {
145110302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall    if (const ObjCObjectPointerType *IfacePtrTy =
145210302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall          IfaceTy->getAs<ObjCObjectPointerType>()) {
145310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall      // Allow non-matching argument types as long as they don't
145410302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall      // violate the principle of substitutability.  Specifically, the
145510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall      // implementation must accept any objects that the superclass
145610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall      // accepts, however it may also accept others.
145710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall      if (isObjCTypeSubstitutable(S.Context, ImplPtrTy, IfacePtrTy, true))
1458fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian        return false;
145910302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall
1460730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian      DiagID =
1461730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian      IsOverridingMode ? diag::warn_non_contravariant_overriding_param_types
1462730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian                       :  diag::warn_non_contravariant_param_types;
146310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall    }
146410302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  }
146510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall
146610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall  S.Diag(ImplVar->getLocation(), DiagID)
146710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall    << getTypeRange(ImplVar->getTypeSourceInfo())
1468730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian    << MethodImpl->getDeclName() << IfaceTy << ImplTy;
1469730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian  S.Diag(IfaceVar->getLocation(),
1470730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian         (IsOverridingMode ? diag::note_previous_declaration
1471730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian                        : diag::note_previous_definition))
147210302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall    << getTypeRange(IfaceVar->getTypeSourceInfo());
1473fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  return false;
147410302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall}
1475f85e193739c953358c865005855253af4f68a497John McCall
1476f85e193739c953358c865005855253af4f68a497John McCall/// In ARC, check whether the conventional meanings of the two methods
1477f85e193739c953358c865005855253af4f68a497John McCall/// match.  If they don't, it's a hard error.
1478f85e193739c953358c865005855253af4f68a497John McCallstatic bool checkMethodFamilyMismatch(Sema &S, ObjCMethodDecl *impl,
1479f85e193739c953358c865005855253af4f68a497John McCall                                      ObjCMethodDecl *decl) {
1480f85e193739c953358c865005855253af4f68a497John McCall  ObjCMethodFamily implFamily = impl->getMethodFamily();
1481f85e193739c953358c865005855253af4f68a497John McCall  ObjCMethodFamily declFamily = decl->getMethodFamily();
1482f85e193739c953358c865005855253af4f68a497John McCall  if (implFamily == declFamily) return false;
1483f85e193739c953358c865005855253af4f68a497John McCall
1484f85e193739c953358c865005855253af4f68a497John McCall  // Since conventions are sorted by selector, the only possibility is
1485f85e193739c953358c865005855253af4f68a497John McCall  // that the types differ enough to cause one selector or the other
1486f85e193739c953358c865005855253af4f68a497John McCall  // to fall out of the family.
1487f85e193739c953358c865005855253af4f68a497John McCall  assert(implFamily == OMF_None || declFamily == OMF_None);
1488f85e193739c953358c865005855253af4f68a497John McCall
1489f85e193739c953358c865005855253af4f68a497John McCall  // No further diagnostics required on invalid declarations.
1490f85e193739c953358c865005855253af4f68a497John McCall  if (impl->isInvalidDecl() || decl->isInvalidDecl()) return true;
1491f85e193739c953358c865005855253af4f68a497John McCall
1492f85e193739c953358c865005855253af4f68a497John McCall  const ObjCMethodDecl *unmatched = impl;
1493f85e193739c953358c865005855253af4f68a497John McCall  ObjCMethodFamily family = declFamily;
1494f85e193739c953358c865005855253af4f68a497John McCall  unsigned errorID = diag::err_arc_lost_method_convention;
1495f85e193739c953358c865005855253af4f68a497John McCall  unsigned noteID = diag::note_arc_lost_method_convention;
1496f85e193739c953358c865005855253af4f68a497John McCall  if (declFamily == OMF_None) {
1497f85e193739c953358c865005855253af4f68a497John McCall    unmatched = decl;
1498f85e193739c953358c865005855253af4f68a497John McCall    family = implFamily;
1499f85e193739c953358c865005855253af4f68a497John McCall    errorID = diag::err_arc_gained_method_convention;
1500f85e193739c953358c865005855253af4f68a497John McCall    noteID = diag::note_arc_gained_method_convention;
1501f85e193739c953358c865005855253af4f68a497John McCall  }
1502f85e193739c953358c865005855253af4f68a497John McCall
1503f85e193739c953358c865005855253af4f68a497John McCall  // Indexes into a %select clause in the diagnostic.
1504f85e193739c953358c865005855253af4f68a497John McCall  enum FamilySelector {
1505f85e193739c953358c865005855253af4f68a497John McCall    F_alloc, F_copy, F_mutableCopy = F_copy, F_init, F_new
1506f85e193739c953358c865005855253af4f68a497John McCall  };
1507f85e193739c953358c865005855253af4f68a497John McCall  FamilySelector familySelector = FamilySelector();
1508f85e193739c953358c865005855253af4f68a497John McCall
1509f85e193739c953358c865005855253af4f68a497John McCall  switch (family) {
1510f85e193739c953358c865005855253af4f68a497John McCall  case OMF_None: llvm_unreachable("logic error, no method convention");
1511f85e193739c953358c865005855253af4f68a497John McCall  case OMF_retain:
1512f85e193739c953358c865005855253af4f68a497John McCall  case OMF_release:
1513f85e193739c953358c865005855253af4f68a497John McCall  case OMF_autorelease:
1514f85e193739c953358c865005855253af4f68a497John McCall  case OMF_dealloc:
151580cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber  case OMF_finalize:
1516f85e193739c953358c865005855253af4f68a497John McCall  case OMF_retainCount:
1517f85e193739c953358c865005855253af4f68a497John McCall  case OMF_self:
1518176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  case OMF_initialize:
15199670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian  case OMF_performSelector:
1520f85e193739c953358c865005855253af4f68a497John McCall    // Mismatches for these methods don't change ownership
1521f85e193739c953358c865005855253af4f68a497John McCall    // conventions, so we don't care.
1522f85e193739c953358c865005855253af4f68a497John McCall    return false;
1523f85e193739c953358c865005855253af4f68a497John McCall
1524f85e193739c953358c865005855253af4f68a497John McCall  case OMF_init: familySelector = F_init; break;
1525f85e193739c953358c865005855253af4f68a497John McCall  case OMF_alloc: familySelector = F_alloc; break;
1526f85e193739c953358c865005855253af4f68a497John McCall  case OMF_copy: familySelector = F_copy; break;
1527f85e193739c953358c865005855253af4f68a497John McCall  case OMF_mutableCopy: familySelector = F_mutableCopy; break;
1528f85e193739c953358c865005855253af4f68a497John McCall  case OMF_new: familySelector = F_new; break;
1529f85e193739c953358c865005855253af4f68a497John McCall  }
1530f85e193739c953358c865005855253af4f68a497John McCall
1531f85e193739c953358c865005855253af4f68a497John McCall  enum ReasonSelector { R_NonObjectReturn, R_UnrelatedReturn };
1532f85e193739c953358c865005855253af4f68a497John McCall  ReasonSelector reasonSelector;
1533f85e193739c953358c865005855253af4f68a497John McCall
1534f85e193739c953358c865005855253af4f68a497John McCall  // The only reason these methods don't fall within their families is
1535f85e193739c953358c865005855253af4f68a497John McCall  // due to unusual result types.
1536651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (unmatched->getReturnType()->isObjCObjectPointerType()) {
1537f85e193739c953358c865005855253af4f68a497John McCall    reasonSelector = R_UnrelatedReturn;
1538f85e193739c953358c865005855253af4f68a497John McCall  } else {
1539f85e193739c953358c865005855253af4f68a497John McCall    reasonSelector = R_NonObjectReturn;
1540f85e193739c953358c865005855253af4f68a497John McCall  }
1541f85e193739c953358c865005855253af4f68a497John McCall
15427348454025693dd20a411c2bcaabd4460cb87559Joerg Sonnenberger  S.Diag(impl->getLocation(), errorID) << int(familySelector) << int(reasonSelector);
15437348454025693dd20a411c2bcaabd4460cb87559Joerg Sonnenberger  S.Diag(decl->getLocation(), noteID) << int(familySelector) << int(reasonSelector);
1544f85e193739c953358c865005855253af4f68a497John McCall
1545f85e193739c953358c865005855253af4f68a497John McCall  return true;
1546f85e193739c953358c865005855253af4f68a497John McCall}
154710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall
15488daab970b80ed2e751fc88327180acbeff1dbb9cFariborz Jahanianvoid Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl,
154921761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian                                       ObjCMethodDecl *MethodDecl,
155036bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian                                       bool IsProtocolMethodDecl) {
15514e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().ObjCAutoRefCount &&
1552f85e193739c953358c865005855253af4f68a497John McCall      checkMethodFamilyMismatch(*this, ImpMethodDecl, MethodDecl))
1553f85e193739c953358c865005855253af4f68a497John McCall    return;
1554f85e193739c953358c865005855253af4f68a497John McCall
155521761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian  CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl,
155636bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian                            IsProtocolMethodDecl, false,
1557730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian                            true);
15581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15593aff919532fd807ed678b9cfa4b7eca7b04adcf9Chris Lattner  for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
15600a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor       IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(),
15610a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor       EF = MethodDecl->param_end();
15620a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor       IM != EM && IF != EF; ++IM, ++IF) {
156321761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian    CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl, *IM, *IF,
156436bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian                             IsProtocolMethodDecl, false, true);
1565561da7e046ea6b39f4e632c68128fd01c985b46bFariborz Jahanian  }
15668daab970b80ed2e751fc88327180acbeff1dbb9cFariborz Jahanian
15672112190efa85f50af84a3c4efe03c5bf69247ba2Fariborz Jahanian  if (ImpMethodDecl->isVariadic() != MethodDecl->isVariadic()) {
156836bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian    Diag(ImpMethodDecl->getLocation(),
156936bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian         diag::warn_conflicting_variadic);
15702112190efa85f50af84a3c4efe03c5bf69247ba2Fariborz Jahanian    Diag(MethodDecl->getLocation(), diag::note_previous_declaration);
15712112190efa85f50af84a3c4efe03c5bf69247ba2Fariborz Jahanian  }
15722112190efa85f50af84a3c4efe03c5bf69247ba2Fariborz Jahanian}
15732112190efa85f50af84a3c4efe03c5bf69247ba2Fariborz Jahanian
157436bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanianvoid Sema::CheckConflictingOverridingMethod(ObjCMethodDecl *Method,
157536bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian                                       ObjCMethodDecl *Overridden,
157636bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian                                       bool IsProtocolMethodDecl) {
157736bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian
157836bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian  CheckMethodOverrideReturn(*this, Method, Overridden,
157936bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian                            IsProtocolMethodDecl, true,
158036bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian                            true);
158136bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian
158236bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian  for (ObjCMethodDecl::param_iterator IM = Method->param_begin(),
15830a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor       IF = Overridden->param_begin(), EM = Method->param_end(),
15840a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor       EF = Overridden->param_end();
15850a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor       IM != EM && IF != EF; ++IM, ++IF) {
158636bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian    CheckMethodOverrideParam(*this, Method, Overridden, *IM, *IF,
158736bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian                             IsProtocolMethodDecl, true, true);
158836bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian  }
158936bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian
159036bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian  if (Method->isVariadic() != Overridden->isVariadic()) {
159136bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian    Diag(Method->getLocation(),
159236bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian         diag::warn_conflicting_overriding_variadic);
159336bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian    Diag(Overridden->getLocation(), diag::note_previous_declaration);
159436bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian  }
159536bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian}
159636bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian
1597fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian/// WarnExactTypedMethods - This routine issues a warning if method
1598fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian/// implementation declaration matches exactly that of its declaration.
1599fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanianvoid Sema::WarnExactTypedMethods(ObjCMethodDecl *ImpMethodDecl,
1600fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian                                 ObjCMethodDecl *MethodDecl,
1601fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian                                 bool IsProtocolMethodDecl) {
1602fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  // don't issue warning when protocol method is optional because primary
1603fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  // class is not required to implement it and it is safe for protocol
1604fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  // to implement it.
1605fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  if (MethodDecl->getImplementationControl() == ObjCMethodDecl::Optional)
1606fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    return;
1607fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  // don't issue warning when primary class's method is
1608fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  // depecated/unavailable.
1609fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  if (MethodDecl->hasAttr<UnavailableAttr>() ||
1610fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian      MethodDecl->hasAttr<DeprecatedAttr>())
1611fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    return;
1612fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian
1613fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  bool match = CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl,
1614fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian                                      IsProtocolMethodDecl, false, false);
1615fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  if (match)
1616fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
16170a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor         IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(),
16180a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor         EF = MethodDecl->param_end();
16190a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor         IM != EM && IF != EF; ++IM, ++IF) {
1620fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian      match = CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl,
1621fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian                                       *IM, *IF,
1622fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian                                       IsProtocolMethodDecl, false, false);
1623fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian      if (!match)
1624fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian        break;
1625fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    }
1626fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  if (match)
1627fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    match = (ImpMethodDecl->isVariadic() == MethodDecl->isVariadic());
16287ca13ef64136929df852c038ebbddee070dc5119David Chisnall  if (match)
16297ca13ef64136929df852c038ebbddee070dc5119David Chisnall    match = !(MethodDecl->isClassMethod() &&
16307ca13ef64136929df852c038ebbddee070dc5119David Chisnall              MethodDecl->getSelector() == GetNullarySelector("load", Context));
1631fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian
1632fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  if (match) {
1633fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    Diag(ImpMethodDecl->getLocation(),
1634fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian         diag::warn_category_method_impl_match);
16353306ec1923973d7b5767b23ba95915af2fec87d7Ted Kremenek    Diag(MethodDecl->getLocation(), diag::note_method_declared_at)
16363306ec1923973d7b5767b23ba95915af2fec87d7Ted Kremenek      << MethodDecl->getDeclName();
1637fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  }
1638fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian}
1639fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian
1640390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump/// FIXME: Type hierarchies in Objective-C can be deep. We could most likely
1641390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump/// improve the efficiency of selector lookups and type checking by associating
1642390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump/// with each protocol / interface / category the flattened instance tables. If
1643390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump/// we used an immutable set to keep the table then it wouldn't add significant
1644390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump/// memory cost and it would be handy for lookups.
1645b20ef3e3fbe0fabe213dc0149011e9f0d751a3a4Daniel Dunbar
1646651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef llvm::DenseSet<IdentifierInfo*> ProtocolNameSet;
1647651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef std::unique_ptr<ProtocolNameSet> LazyProtocolNameSet;
1648651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1649651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void findProtocolsWithExplicitImpls(const ObjCProtocolDecl *PDecl,
1650651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                           ProtocolNameSet &PNS) {
1651651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (PDecl->hasAttr<ObjCExplicitProtocolImplAttr>())
1652651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PNS.insert(PDecl->getIdentifier());
1653651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *PI : PDecl->protocols())
1654651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    findProtocolsWithExplicitImpls(PI, PNS);
1655651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
1656651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1657651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Recursively populates a set with all conformed protocols in a class
1658651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// hierarchy that have the 'objc_protocol_requires_explicit_implementation'
1659651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// attribute.
1660651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void findProtocolsWithExplicitImpls(const ObjCInterfaceDecl *Super,
1661651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                           ProtocolNameSet &PNS) {
1662651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!Super)
1663651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return;
1664651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1665651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *I : Super->all_referenced_protocols())
1666651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    findProtocolsWithExplicitImpls(I, PNS);
1667651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1668651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  findProtocolsWithExplicitImpls(Super->getSuperClass(), PNS);
1669651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
1670651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1671efe7f36f4d87b6e64b87128a81018350b2f21987Steve Naroff/// CheckProtocolMethodDefs - This routine checks unimplemented methods
16724d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// Declared in protocol, and those referenced by it.
1673651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void CheckProtocolMethodDefs(Sema &S,
1674651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    SourceLocation ImpLoc,
1675651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    ObjCProtocolDecl *PDecl,
1676651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    bool& IncompleteImpl,
1677651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    const Sema::SelectorSet &InsMap,
1678651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    const Sema::SelectorSet &ClsMap,
1679651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    ObjCContainerDecl *CDecl,
1680651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    LazyProtocolNameSet &ProtocolsExplictImpl) {
1681bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian  ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl);
1682bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian  ObjCInterfaceDecl *IDecl = C ? C->getClassInterface()
1683bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian                               : dyn_cast<ObjCInterfaceDecl>(CDecl);
1684f28385991fa724ac0bd6017d709f17b1838cfea3Fariborz Jahanian  assert (IDecl && "CheckProtocolMethodDefs - IDecl is null");
1685f28385991fa724ac0bd6017d709f17b1838cfea3Fariborz Jahanian
16867ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar  ObjCInterfaceDecl *Super = IDecl->getSuperClass();
16876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ObjCInterfaceDecl *NSIDecl = nullptr;
1688651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1689651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // If this protocol is marked 'objc_protocol_requires_explicit_implementation'
1690651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // then we should check if any class in the super class hierarchy also
1691651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // conforms to this protocol, either directly or via protocol inheritance.
1692651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // If so, we can skip checking this protocol completely because we
1693651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // know that a parent class already satisfies this protocol.
1694651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  //
1695651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Note: we could generalize this logic for all protocols, and merely
1696651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // add the limit on looking at the super class chain for just
1697651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // specially marked protocols.  This may be a good optimization.  This
1698651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // change is restricted to 'objc_protocol_requires_explicit_implementation'
1699651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // protocols for now for controlled evaluation.
1700651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (PDecl->hasAttr<ObjCExplicitProtocolImplAttr>()) {
1701651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (!ProtocolsExplictImpl) {
1702651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ProtocolsExplictImpl.reset(new ProtocolNameSet);
1703651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      findProtocolsWithExplicitImpls(Super, *ProtocolsExplictImpl);
1704651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
1705651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (ProtocolsExplictImpl->find(PDecl->getIdentifier()) !=
1706651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        ProtocolsExplictImpl->end())
1707651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return;
1708651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1709651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // If no super class conforms to the protocol, we should not search
1710651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // for methods in the super class to implicitly satisfy the protocol.
17116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    Super = nullptr;
1712651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
1713651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1714651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (S.getLangOpts().ObjCRuntime.isNeXTFamily()) {
17151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // check to see if class implements forwardInvocation method and objects
17161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // of this class are derived from 'NSProxy' so that to forward requests
1717cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian    // from one object to another.
17181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Under such conditions, which means that every method possible is
17191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // implemented in the class, we should not issue "Method definition not
1720cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian    // found" warnings.
1721cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian    // FIXME: Use a general GetUnarySelector method for this.
1722651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    IdentifierInfo* II = &S.Context.Idents.get("forwardInvocation");
1723651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Selector fISelector = S.Context.Selectors.getSelector(1, &II);
1724cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian    if (InsMap.count(fISelector))
1725cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian      // Is IDecl derived from 'NSProxy'? If so, no instance methods
1726cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian      // need be implemented in the implementation.
1727651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      NSIDecl = IDecl->lookupInheritedClass(&S.Context.Idents.get("NSProxy"));
1728cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian  }
17291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
173032b94bedc6a789e4091626e7433e73555cf9df00Fariborz Jahanian  // If this is a forward protocol declaration, get its definition.
173132b94bedc6a789e4091626e7433e73555cf9df00Fariborz Jahanian  if (!PDecl->isThisDeclarationADefinition() &&
173232b94bedc6a789e4091626e7433e73555cf9df00Fariborz Jahanian      PDecl->getDefinition())
173332b94bedc6a789e4091626e7433e73555cf9df00Fariborz Jahanian    PDecl = PDecl->getDefinition();
173432b94bedc6a789e4091626e7433e73555cf9df00Fariborz Jahanian
17357ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar  // If a method lookup fails locally we still need to look and see if
17367ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar  // the method was implemented by a base class or an inherited
17377ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar  // protocol. This lookup is slow, but occurs rarely in correct code
17387ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar  // and otherwise would terminate in a warning.
17397ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar
17404d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // check unimplemented instance methods.
1741cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian  if (!NSIDecl)
1742651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (auto *method : PDecl->instance_methods()) {
17431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
17441e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose          !method->isPropertyAccessor() &&
17451e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose          !InsMap.count(method->getSelector()) &&
1746651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          (!Super || !Super->lookupMethod(method->getSelector(),
1747651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                          true /* instance */,
1748651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                          false /* shallowCategory */,
1749651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                          true /* followsSuper */,
17506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                          nullptr /* category */))) {
1751bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian            // If a method is not implemented in the category implementation but
1752bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian            // has been declared in its primary class, superclass,
1753bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian            // or in one of their protocols, no need to issue the warning.
1754bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian            // This is because method will be implemented in the primary class
1755bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian            // or one of its super class implementation.
1756bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian
1757cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian            // Ugly, but necessary. Method declared in protcol might have
1758cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian            // have been synthesized due to a property declared in the class which
1759cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian            // uses the protocol.
1760bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian            if (ObjCMethodDecl *MethodInClass =
1761651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                  IDecl->lookupMethod(method->getSelector(),
1762651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                      true /* instance */,
1763651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                      true /* shallowCategoryLookup */,
1764651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                      false /* followSuper */))
17651e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose              if (C || MethodInClass->isPropertyAccessor())
1766bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian                continue;
1767bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian            unsigned DIAG = diag::warn_unimplemented_protocol_method;
1768c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines            if (!S.Diags.isIgnored(DIAG, ImpLoc)) {
1769651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG,
1770651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                  PDecl);
17718822f7cda557ffa755c16b5c978dada23c37d6beFariborz Jahanian            }
1772cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian          }
1773cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian    }
17744d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // check unimplemented class methods
1775651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *method : PDecl->class_methods()) {
17767ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar    if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
17777ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar        !ClsMap.count(method->getSelector()) &&
1778651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        (!Super || !Super->lookupMethod(method->getSelector(),
1779651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                        false /* class method */,
1780651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                        false /* shallowCategoryLookup */,
1781651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                        true  /* followSuper */,
17826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                        nullptr /* category */))) {
1783bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian      // See above comment for instance method lookups.
1784651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (C && IDecl->lookupMethod(method->getSelector(),
1785651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   false /* class */,
1786651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   true /* shallowCategoryLookup */,
1787651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   false /* followSuper */))
1788bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian        continue;
1789651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1790521468391c0abbbfcf6b257442630c70314b8576Fariborz Jahanian      unsigned DIAG = diag::warn_unimplemented_protocol_method;
1791c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      if (!S.Diags.isIgnored(DIAG, ImpLoc)) {
1792651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, PDecl);
1793521468391c0abbbfcf6b257442630c70314b8576Fariborz Jahanian      }
17948822f7cda557ffa755c16b5c978dada23c37d6beFariborz Jahanian    }
179558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff  }
1796780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner  // Check on this protocols's referenced protocols, recursively.
1797651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *PI : PDecl->protocols())
1798651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    CheckProtocolMethodDefs(S, ImpLoc, PI, IncompleteImpl, InsMap, ClsMap,
1799651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                            CDecl, ProtocolsExplictImpl);
18004d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
18014d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
18021e159bc43cf6575a415dbe8deb7fc49611002ffeFariborz Jahanian/// MatchAllMethodDeclarations - Check methods declared in interface
1803b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian/// or protocol against those declared in their implementations.
1804b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian///
1805811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramervoid Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap,
1806811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer                                      const SelectorSet &ClsMap,
1807811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer                                      SelectorSet &InsMapSeen,
1808811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer                                      SelectorSet &ClsMapSeen,
1809b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian                                      ObjCImplDecl* IMPDecl,
1810b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian                                      ObjCContainerDecl* CDecl,
1811b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian                                      bool &IncompleteImpl,
1812fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian                                      bool ImmediateClass,
1813bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian                                      bool WarnCategoryMethodImpl) {
1814b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian  // Check and see if instance methods in class interface have been
1815b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian  // implemented in the implementation class. If so, their types match.
1816651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *I : CDecl->instance_methods()) {
1817176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (!InsMapSeen.insert(I->getSelector()).second)
18187dcff5b56bc470c456f70ecb124c3a9013c50953Benjamin Kramer      continue;
1819651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (!I->isPropertyAccessor() &&
1820651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        !InsMap.count(I->getSelector())) {
1821b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian      if (ImmediateClass)
1822651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        WarnUndefinedMethod(*this, IMPDecl->getLocation(), I, IncompleteImpl,
18238b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek                            diag::warn_undef_method_impl);
1824b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian      continue;
1825ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
18261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      ObjCMethodDecl *ImpMethodDecl =
1827651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        IMPDecl->getInstanceMethod(I->getSelector());
1828651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      assert(CDecl->getInstanceMethod(I->getSelector()) &&
18292334f3aeda318f68e763379afa5ac7a91b90caa7Argyrios Kyrtzidis             "Expected to find the method through lookup as well");
1830b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian      // ImpMethodDecl may be null as in a @dynamic property.
1831fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian      if (ImpMethodDecl) {
1832bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian        if (!WarnCategoryMethodImpl)
1833651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          WarnConflictingTypedMethods(ImpMethodDecl, I,
1834fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian                                      isa<ObjCProtocolDecl>(CDecl));
1835651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        else if (!I->isPropertyAccessor())
1836651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          WarnExactTypedMethods(ImpMethodDecl, I, isa<ObjCProtocolDecl>(CDecl));
1837fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian      }
1838b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian    }
1839b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian  }
18401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1841b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian  // Check and see if class methods in class interface have been
1842b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian  // implemented in the implementation class. If so, their types match.
1843651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *I : CDecl->class_methods()) {
1844176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (!ClsMapSeen.insert(I->getSelector()).second)
18457dcff5b56bc470c456f70ecb124c3a9013c50953Benjamin Kramer      continue;
1846651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (!ClsMap.count(I->getSelector())) {
1847b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian      if (ImmediateClass)
1848651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        WarnUndefinedMethod(*this, IMPDecl->getLocation(), I, IncompleteImpl,
18498b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek                            diag::warn_undef_method_impl);
1850ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
185117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      ObjCMethodDecl *ImpMethodDecl =
1852651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        IMPDecl->getClassMethod(I->getSelector());
1853651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      assert(CDecl->getClassMethod(I->getSelector()) &&
18542334f3aeda318f68e763379afa5ac7a91b90caa7Argyrios Kyrtzidis             "Expected to find the method through lookup as well");
1855bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian      if (!WarnCategoryMethodImpl)
1856651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        WarnConflictingTypedMethods(ImpMethodDecl, I,
1857fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian                                    isa<ObjCProtocolDecl>(CDecl));
1858fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian      else
1859651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        WarnExactTypedMethods(ImpMethodDecl, I,
1860bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian                              isa<ObjCProtocolDecl>(CDecl));
1861b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian    }
1862b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian  }
1863f54e3aec8a12c3ce453b1012e686c4b88881564aFariborz Jahanian
186441594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian  if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl> (CDecl)) {
186541594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian    // Also, check for methods declared in protocols inherited by
186641594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian    // this protocol.
1867651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (auto *PI : PD->protocols())
186841594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian      MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1869651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 IMPDecl, PI, IncompleteImpl, false,
187041594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian                                 WarnCategoryMethodImpl);
187141594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian  }
187241594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian
1873b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian  if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
18746a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian    // when checking that methods in implementation match their declaration,
18756a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian    // i.e. when WarnCategoryMethodImpl is false, check declarations in class
18766a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian    // extension; as well as those in categories.
1877d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    if (!WarnCategoryMethodImpl) {
1878651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      for (auto *Cat : I->visible_categories())
18796a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian        MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1880651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   IMPDecl, Cat, IncompleteImpl, false,
18816a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian                                   WarnCategoryMethodImpl);
1882d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    } else {
18836a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian      // Also methods in class extensions need be looked at next.
1884651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      for (auto *Ext : I->visible_extensions())
18856a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian        MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1886651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   IMPDecl, Ext, IncompleteImpl, false,
18876a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian                                   WarnCategoryMethodImpl);
1888d329724745b49f894b768d47275b7c2713106e89Douglas Gregor    }
1889d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
1890b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian    // Check for any implementation of a methods declared in protocol.
1891651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (auto *PI : I->all_referenced_protocols())
18921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1893651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 IMPDecl, PI, IncompleteImpl, false,
1894bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian                                 WarnCategoryMethodImpl);
1895651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1896fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    // FIXME. For now, we are not checking for extact match of methods
1897fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    // in category implementation and its primary class's super class.
1898bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian    if (!WarnCategoryMethodImpl && I->getSuperClass())
1899b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian      MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
19001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                 IMPDecl,
1901b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian                                 I->getSuperClass(), IncompleteImpl, false);
1902b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian  }
1903b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian}
1904b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian
1905fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian/// CheckCategoryVsClassMethodMatches - Checks that methods implemented in
1906fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian/// category matches with those implemented in its primary class and
1907fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian/// warns each time an exact match is found.
1908fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanianvoid Sema::CheckCategoryVsClassMethodMatches(
1909fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian                                  ObjCCategoryImplDecl *CatIMPDecl) {
1910fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  // Get category's primary class.
1911fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  ObjCCategoryDecl *CatDecl = CatIMPDecl->getCategoryDecl();
1912fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  if (!CatDecl)
1913fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    return;
1914fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  ObjCInterfaceDecl *IDecl = CatDecl->getClassInterface();
1915fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  if (!IDecl)
1916fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    return;
1917651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ObjCInterfaceDecl *SuperIDecl = IDecl->getSuperClass();
1918651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SelectorSet InsMap, ClsMap;
1919651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1920651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *I : CatIMPDecl->instance_methods()) {
1921651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Selector Sel = I->getSelector();
1922651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // When checking for methods implemented in the category, skip over
1923651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // those declared in category class's super class. This is because
1924651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // the super class must implement the method.
1925651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (SuperIDecl && SuperIDecl->lookupMethod(Sel, true))
1926651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      continue;
1927651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    InsMap.insert(Sel);
1928651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
1929651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1930651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *I : CatIMPDecl->class_methods()) {
1931651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Selector Sel = I->getSelector();
1932651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (SuperIDecl && SuperIDecl->lookupMethod(Sel, false))
1933651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      continue;
1934651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ClsMap.insert(Sel);
1935651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
1936651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (InsMap.empty() && ClsMap.empty())
1937651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return;
1938651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1939811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer  SelectorSet InsMapSeen, ClsMapSeen;
1940fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  bool IncompleteImpl = false;
1941fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1942fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian                             CatIMPDecl, IDecl,
1943bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian                             IncompleteImpl, false,
1944bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian                             true /*WarnCategoryMethodImpl*/);
1945fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian}
1946eee3ef177a171c06f826c331e7a9e256d01eaeb0Fariborz Jahanian
194717cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanianvoid Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
19481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     ObjCContainerDecl* CDecl,
1949cddc88800bbd1213ec70ae5153c6a7f2e380fd8dChris Lattner                                     bool IncompleteImpl) {
1950811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer  SelectorSet InsMap;
19514d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // Check and see if instance methods in class interface have been
19524d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // implemented in the implementation class.
1953651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *I : IMPDecl->instance_methods())
1954651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    InsMap.insert(I->getSelector());
19551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
195612bac2566e3136d4bd9d42e6aabe27e1038f7793Fariborz Jahanian  // Check and see if properties declared in the interface have either 1)
195712bac2566e3136d4bd9d42e6aabe27e1038f7793Fariborz Jahanian  // an implementation or 2) there is a @synthesize/@dynamic implementation
195812bac2566e3136d4bd9d42e6aabe27e1038f7793Fariborz Jahanian  // of the property in the @implementation.
1959651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (const ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
1960651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    bool SynthesizeProperties = LangOpts.ObjCDefaultSynthProperties &&
1961651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                LangOpts.ObjCRuntime.isNonFragile() &&
1962651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                !IDecl->isObjCRequiresPropertyDefs();
1963651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, SynthesizeProperties);
1964651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
1965651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1966811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer  SelectorSet ClsMap;
1967651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *I : IMPDecl->class_methods())
1968651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ClsMap.insert(I->getSelector());
19691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1970b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian  // Check for type conflict of methods declared in a class/protocol and
1971b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian  // its implementation; if any.
1972811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer  SelectorSet InsMapSeen, ClsMapSeen;
19731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
19741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                             IMPDecl, CDecl,
1975b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian                             IncompleteImpl, true);
197674133075f5024ce87e4c1eb644d77c20e1c521f4Fariborz Jahanian
1977fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  // check all methods implemented in category against those declared
1978fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  // in its primary class.
1979fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian  if (ObjCCategoryImplDecl *CatDecl =
1980fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian        dyn_cast<ObjCCategoryImplDecl>(IMPDecl))
1981fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian    CheckCategoryVsClassMethodMatches(CatDecl);
19821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19834d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // Check the protocol list for unimplemented methods in the @implementation
19844d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  // class.
1985b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian  // Check and see if class methods in class interface have been
1986b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian  // implemented in the implementation class.
19871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1988651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  LazyProtocolNameSet ExplicitImplProtocols;
1989651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1990cddc88800bbd1213ec70ae5153c6a7f2e380fd8dChris Lattner  if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
1991651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (auto *PI : I->all_referenced_protocols())
1992651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), PI, IncompleteImpl,
1993651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                              InsMap, ClsMap, I, ExplicitImplProtocols);
1994cddc88800bbd1213ec70ae5153c6a7f2e380fd8dChris Lattner    // Check class extensions (unnamed categories)
1995651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (auto *Ext : I->visible_extensions())
1996651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ImplMethodsVsClassMethods(S, IMPDecl, Ext, IncompleteImpl);
1997cddc88800bbd1213ec70ae5153c6a7f2e380fd8dChris Lattner  } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
1998b106fc635b1523952332131785b700453a936e49Fariborz Jahanian    // For extended class, unimplemented methods in its protocols will
1999b106fc635b1523952332131785b700453a936e49Fariborz Jahanian    // be reported in the primary class.
200025760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian    if (!C->IsClassExtension()) {
2001651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      for (auto *P : C->protocols())
2002651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), P,
2003651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                IncompleteImpl, InsMap, ClsMap, CDecl,
2004651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                ExplicitImplProtocols);
2005651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      DiagnoseUnimplementedProperties(S, IMPDecl, CDecl,
20060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                      /*SynthesizeProperties=*/false);
20073ad230eb626d630877c17d6e81b167ec7476d84eFariborz Jahanian    }
2008cddc88800bbd1213ec70ae5153c6a7f2e380fd8dChris Lattner  } else
2009b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie    llvm_unreachable("invalid ObjCContainerDecl type.");
20104d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
20114d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
201295ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz JahanianSema::DeclGroupPtrTy
20134d3914836e85258e9ace7306999413e3c7ea6c11Chris LattnerSema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
2014bdbde4db74ea9751e02081d720f415eae9718662Chris Lattner                                   IdentifierInfo **IdentList,
2015c09cba67d0ad01e53e0fed07322e95dd281bcfd9Ted Kremenek                                   SourceLocation *IdentLocs,
2016bdbde4db74ea9751e02081d720f415eae9718662Chris Lattner                                   unsigned NumElts) {
201795ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian  SmallVector<Decl *, 8> DeclsInGroup;
20184d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  for (unsigned i = 0; i != NumElts; ++i) {
20194d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    // Check for another declaration kind with the same name.
2020f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall    NamedDecl *PrevDecl
2021c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor      = LookupSingleName(TUScope, IdentList[i], IdentLocs[i],
2022c0b39640de335809ca7544f802751112619f30ccDouglas Gregor                         LookupOrdinaryName, ForRedeclaration);
2023a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
2024c7333881dcd00be87814d03c349dd96c815f2f05Steve Naroff      // GCC apparently allows the following idiom:
2025c7333881dcd00be87814d03c349dd96c815f2f05Steve Naroff      //
2026c7333881dcd00be87814d03c349dd96c815f2f05Steve Naroff      // typedef NSObject < XCElementTogglerP > XCElementToggler;
2027c7333881dcd00be87814d03c349dd96c815f2f05Steve Naroff      // @class XCElementToggler;
2028c7333881dcd00be87814d03c349dd96c815f2f05Steve Naroff      //
2029e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian      // Here we have chosen to ignore the forward class declaration
2030e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian      // with a warning. Since this is the implied behavior.
2031162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(PrevDecl);
2032c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall      if (!TDD || !TDD->getUnderlyingType()->isObjCObjectType()) {
20333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        Diag(AtClassLoc, diag::err_redefinition_different_kind) << IdentList[i];
20345f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner        Diag(PrevDecl->getLocation(), diag::note_previous_definition);
2035c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall      } else {
2036ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump        // a forward class declaration matching a typedef name of a class refers
2037e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian        // to the underlying class. Just ignore the forward class with a warning
20380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        // as this will force the intended behavior which is to lookup the
20390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        // typedef name.
2040e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian        if (isa<ObjCObjectType>(TDD->getUnderlyingType())) {
20410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines          Diag(AtClassLoc, diag::warn_forward_class_redefinition)
20420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines              << IdentList[i];
2043e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian          Diag(PrevDecl->getLocation(), diag::note_previous_definition);
2044e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian          continue;
2045e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian        }
2046cae27c51f0da674cdd3b53b8b2f7ba08c44c54b0Fariborz Jahanian      }
20474d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    }
20487723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor
20497723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor    // Create a declaration to describe this forward declaration.
20500af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor    ObjCInterfaceDecl *PrevIDecl
20510af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor      = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
2052e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis
2053e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis    IdentifierInfo *ClassName = IdentList[i];
2054e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis    if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) {
2055e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis      // A previous decl with a different name is because of
2056e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis      // @compatibility_alias, for example:
2057e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis      // \code
2058e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis      //   @class NewImage;
2059e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis      //   @compatibility_alias OldImage NewImage;
2060e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis      // \endcode
2061e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis      // A lookup for 'OldImage' will return the 'NewImage' decl.
2062e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis      //
2063e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis      // In such a case use the real declaration name, instead of the alias one,
2064e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis      // otherwise we will break IdentifierResolver and redecls-chain invariants.
2065e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis      // FIXME: If necessary, add a bit to indicate that this ObjCInterfaceDecl
2066e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis      // has been aliased.
2067e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis      ClassName = PrevIDecl->getIdentifier();
2068e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis    }
2069e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis
20707723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor    ObjCInterfaceDecl *IDecl
20717723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor      = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
2072e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis                                  ClassName, PrevIDecl, IdentLocs[i]);
20737723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor    IDecl->setAtEndRange(IdentLocs[i]);
20747723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor
20757723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor    PushOnScopeChains(IDecl, TUScope);
2076375bb1413c041055262c8a416f20d10474a5eda9Douglas Gregor    CheckObjCDeclScope(IDecl);
2077375bb1413c041055262c8a416f20d10474a5eda9Douglas Gregor    DeclsInGroup.push_back(IDecl);
20784d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
20794549d7ffc15bdd7ab860aa68db089d9f559b79e7Rafael Espindola
20804549d7ffc15bdd7ab860aa68db089d9f559b79e7Rafael Espindola  return BuildDeclaratorGroup(DeclsInGroup, false);
20814d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
20824d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
20830f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCallstatic bool tryMatchRecordTypes(ASTContext &Context,
20840f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall                                Sema::MethodMatchStrategy strategy,
20850f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall                                const Type *left, const Type *right);
20860f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall
2087f85e193739c953358c865005855253af4f68a497John McCallstatic bool matchTypes(ASTContext &Context, Sema::MethodMatchStrategy strategy,
2088f85e193739c953358c865005855253af4f68a497John McCall                       QualType leftQT, QualType rightQT) {
2089f85e193739c953358c865005855253af4f68a497John McCall  const Type *left =
2090f85e193739c953358c865005855253af4f68a497John McCall    Context.getCanonicalType(leftQT).getUnqualifiedType().getTypePtr();
2091f85e193739c953358c865005855253af4f68a497John McCall  const Type *right =
2092f85e193739c953358c865005855253af4f68a497John McCall    Context.getCanonicalType(rightQT).getUnqualifiedType().getTypePtr();
2093f85e193739c953358c865005855253af4f68a497John McCall
2094f85e193739c953358c865005855253af4f68a497John McCall  if (left == right) return true;
2095f85e193739c953358c865005855253af4f68a497John McCall
2096f85e193739c953358c865005855253af4f68a497John McCall  // If we're doing a strict match, the types have to match exactly.
2097f85e193739c953358c865005855253af4f68a497John McCall  if (strategy == Sema::MMS_strict) return false;
2098f85e193739c953358c865005855253af4f68a497John McCall
2099f85e193739c953358c865005855253af4f68a497John McCall  if (left->isIncompleteType() || right->isIncompleteType()) return false;
2100f85e193739c953358c865005855253af4f68a497John McCall
2101f85e193739c953358c865005855253af4f68a497John McCall  // Otherwise, use this absurdly complicated algorithm to try to
2102f85e193739c953358c865005855253af4f68a497John McCall  // validate the basic, low-level compatibility of the two types.
2103f85e193739c953358c865005855253af4f68a497John McCall
2104f85e193739c953358c865005855253af4f68a497John McCall  // As a minimum, require the sizes and alignments to match.
2105176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  TypeInfo LeftTI = Context.getTypeInfo(left);
2106176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  TypeInfo RightTI = Context.getTypeInfo(right);
2107176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (LeftTI.Width != RightTI.Width)
2108176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return false;
2109176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
2110176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (LeftTI.Align != RightTI.Align)
2111f85e193739c953358c865005855253af4f68a497John McCall    return false;
2112f85e193739c953358c865005855253af4f68a497John McCall
2113f85e193739c953358c865005855253af4f68a497John McCall  // Consider all the kinds of non-dependent canonical types:
2114f85e193739c953358c865005855253af4f68a497John McCall  // - functions and arrays aren't possible as return and parameter types
2115f85e193739c953358c865005855253af4f68a497John McCall
2116f85e193739c953358c865005855253af4f68a497John McCall  // - vector types of equal size can be arbitrarily mixed
2117f85e193739c953358c865005855253af4f68a497John McCall  if (isa<VectorType>(left)) return isa<VectorType>(right);
2118f85e193739c953358c865005855253af4f68a497John McCall  if (isa<VectorType>(right)) return false;
2119f85e193739c953358c865005855253af4f68a497John McCall
2120f85e193739c953358c865005855253af4f68a497John McCall  // - references should only match references of identical type
21210f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  // - structs, unions, and Objective-C objects must match more-or-less
21220f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  //   exactly
2123f85e193739c953358c865005855253af4f68a497John McCall  // - everything else should be a scalar
2124f85e193739c953358c865005855253af4f68a497John McCall  if (!left->isScalarType() || !right->isScalarType())
21250f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall    return tryMatchRecordTypes(Context, strategy, left, right);
2126f85e193739c953358c865005855253af4f68a497John McCall
21271d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  // Make scalars agree in kind, except count bools as chars, and group
21281d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  // all non-member pointers together.
2129f85e193739c953358c865005855253af4f68a497John McCall  Type::ScalarTypeKind leftSK = left->getScalarTypeKind();
2130f85e193739c953358c865005855253af4f68a497John McCall  Type::ScalarTypeKind rightSK = right->getScalarTypeKind();
2131f85e193739c953358c865005855253af4f68a497John McCall  if (leftSK == Type::STK_Bool) leftSK = Type::STK_Integral;
2132f85e193739c953358c865005855253af4f68a497John McCall  if (rightSK == Type::STK_Bool) rightSK = Type::STK_Integral;
21331d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  if (leftSK == Type::STK_CPointer || leftSK == Type::STK_BlockPointer)
21341d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    leftSK = Type::STK_ObjCObjectPointer;
21351d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  if (rightSK == Type::STK_CPointer || rightSK == Type::STK_BlockPointer)
21361d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    rightSK = Type::STK_ObjCObjectPointer;
2137f85e193739c953358c865005855253af4f68a497John McCall
2138f85e193739c953358c865005855253af4f68a497John McCall  // Note that data member pointers and function member pointers don't
2139f85e193739c953358c865005855253af4f68a497John McCall  // intermix because of the size differences.
2140f85e193739c953358c865005855253af4f68a497John McCall
2141f85e193739c953358c865005855253af4f68a497John McCall  return (leftSK == rightSK);
2142f85e193739c953358c865005855253af4f68a497John McCall}
21434d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
21440f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCallstatic bool tryMatchRecordTypes(ASTContext &Context,
21450f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall                                Sema::MethodMatchStrategy strategy,
21460f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall                                const Type *lt, const Type *rt) {
21470f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  assert(lt && rt && lt != rt);
21480f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall
21490f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  if (!isa<RecordType>(lt) || !isa<RecordType>(rt)) return false;
21500f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  RecordDecl *left = cast<RecordType>(lt)->getDecl();
21510f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  RecordDecl *right = cast<RecordType>(rt)->getDecl();
21520f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall
21530f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  // Require union-hood to match.
21540f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  if (left->isUnion() != right->isUnion()) return false;
21550f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall
21560f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  // Require an exact match if either is non-POD.
21570f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  if ((isa<CXXRecordDecl>(left) && !cast<CXXRecordDecl>(left)->isPOD()) ||
21580f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall      (isa<CXXRecordDecl>(right) && !cast<CXXRecordDecl>(right)->isPOD()))
21590f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall    return false;
21600f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall
21610f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  // Require size and alignment to match.
2162176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  TypeInfo LeftTI = Context.getTypeInfo(lt);
2163176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  TypeInfo RightTI = Context.getTypeInfo(rt);
2164176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (LeftTI.Width != RightTI.Width)
2165176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return false;
2166176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
2167176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (LeftTI.Align != RightTI.Align)
2168176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return false;
21690f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall
21700f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  // Require fields to match.
21710f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  RecordDecl::field_iterator li = left->field_begin(), le = left->field_end();
21720f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  RecordDecl::field_iterator ri = right->field_begin(), re = right->field_end();
21730f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  for (; li != le && ri != re; ++li, ++ri) {
21740f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall    if (!matchTypes(Context, strategy, li->getType(), ri->getType()))
21750f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall      return false;
21760f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  }
21770f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall  return (li == le && ri == re);
21780f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall}
21790f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall
21804d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// MatchTwoMethodDeclarations - Checks that two methods have matching type and
21814d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// returns true, or false, accordingly.
21824d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// TODO: Handle protocol list; such as id<p1,p2> in type comparisons
2183f85e193739c953358c865005855253af4f68a497John McCallbool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *left,
2184f85e193739c953358c865005855253af4f68a497John McCall                                      const ObjCMethodDecl *right,
2185f85e193739c953358c865005855253af4f68a497John McCall                                      MethodMatchStrategy strategy) {
2186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!matchTypes(Context, strategy, left->getReturnType(),
2187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                  right->getReturnType()))
2188f85e193739c953358c865005855253af4f68a497John McCall    return false;
21891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21907666b03d499819214752ae392efe666ca856d0e7Douglas Gregor  // If either is hidden, it is not considered to match.
21917666b03d499819214752ae392efe666ca856d0e7Douglas Gregor  if (left->isHidden() || right->isHidden())
21927666b03d499819214752ae392efe666ca856d0e7Douglas Gregor    return false;
21937666b03d499819214752ae392efe666ca856d0e7Douglas Gregor
21944e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().ObjCAutoRefCount &&
2195f85e193739c953358c865005855253af4f68a497John McCall      (left->hasAttr<NSReturnsRetainedAttr>()
2196f85e193739c953358c865005855253af4f68a497John McCall         != right->hasAttr<NSReturnsRetainedAttr>() ||
2197f85e193739c953358c865005855253af4f68a497John McCall       left->hasAttr<NSConsumesSelfAttr>()
2198f85e193739c953358c865005855253af4f68a497John McCall         != right->hasAttr<NSConsumesSelfAttr>()))
2199f85e193739c953358c865005855253af4f68a497John McCall    return false;
22001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2201491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  ObjCMethodDecl::param_const_iterator
22020a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor    li = left->param_begin(), le = left->param_end(), ri = right->param_begin(),
22030a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor    re = right->param_end();
2204f85e193739c953358c865005855253af4f68a497John McCall
22050a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor  for (; li != le && ri != re; ++li, ++ri) {
2206f85e193739c953358c865005855253af4f68a497John McCall    assert(ri != right->param_end() && "Param mismatch");
2207491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis    const ParmVarDecl *lparm = *li, *rparm = *ri;
2208f85e193739c953358c865005855253af4f68a497John McCall
2209f85e193739c953358c865005855253af4f68a497John McCall    if (!matchTypes(Context, strategy, lparm->getType(), rparm->getType()))
2210f85e193739c953358c865005855253af4f68a497John McCall      return false;
2211f85e193739c953358c865005855253af4f68a497John McCall
22124e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (getLangOpts().ObjCAutoRefCount &&
2213f85e193739c953358c865005855253af4f68a497John McCall        lparm->hasAttr<NSConsumedAttr>() != rparm->hasAttr<NSConsumedAttr>())
2214f85e193739c953358c865005855253af4f68a497John McCall      return false;
22154d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
22164d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  return true;
22174d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
22184d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
22190e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid Sema::addMethodToGlobalList(ObjCMethodList *List,
22200e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                 ObjCMethodDecl *Method) {
22212e3d8c0815acaf1bc5995ebe56cea07471e5c9c7Argyrios Kyrtzidis  // Record at the head of the list whether there were 0, 1, or >= 2 methods
22222e3d8c0815acaf1bc5995ebe56cea07471e5c9c7Argyrios Kyrtzidis  // inside categories.
22230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  if (ObjCCategoryDecl *CD =
22240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines          dyn_cast<ObjCCategoryDecl>(Method->getDeclContext()))
2225ab3d509bc45218c278454962ff644bb13d18ce1aArgyrios Kyrtzidis    if (!CD->IsClassExtension() && List->getBits() < 2)
22260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      List->setBits(List->getBits() + 1);
22272e3d8c0815acaf1bc5995ebe56cea07471e5c9c7Argyrios Kyrtzidis
222844fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor  // If the list is empty, make it a singleton list.
22290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  if (List->getMethod() == nullptr) {
22300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    List->setMethod(Method);
22316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    List->setNext(nullptr);
2232ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor    return;
223344fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor  }
22340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
223544fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor  // We've seen a method with this name, see if we have already seen this type
223644fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor  // signature.
223744fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor  ObjCMethodList *Previous = List;
22382e3d8c0815acaf1bc5995ebe56cea07471e5c9c7Argyrios Kyrtzidis  for (; List; Previous = List, List = List->getNext()) {
2239fc46be997f8219e11900473c373b639525396064Douglas Gregor    // If we are building a module, keep all of the methods.
2240fc46be997f8219e11900473c373b639525396064Douglas Gregor    if (getLangOpts().Modules && !getLangOpts().CurrentModule.empty())
2241fc46be997f8219e11900473c373b639525396064Douglas Gregor      continue;
2242fc46be997f8219e11900473c373b639525396064Douglas Gregor
224333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar    if (!MatchTwoMethodDeclarations(Method, List->getMethod())) {
224433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar      // Even if two method types do not match, we would like to say
224533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar      // there is more than one declaration so unavailability/deprecated
224633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar      // warning is not too noisy.
224733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar      if (!Method->isDefined())
224833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar        List->setHasMoreThanOneDecl(true);
224944fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor      continue;
225033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar    }
22510e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
22520e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    ObjCMethodDecl *PrevObjCMethod = List->getMethod();
225344fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor
225444fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor    // Propagate the 'defined' bit.
225544fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor    if (Method->isDefined())
225644fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor      PrevObjCMethod->setDefined(true);
22570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    else {
22580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      // Objective-C doesn't allow an @interface for a class after its
22590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      // @implementation. So if Method is not defined and there already is
22600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      // an entry for this type signature, Method has to be for a different
22610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      // class than PrevObjCMethod.
22620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      List->setHasMoreThanOneDecl(true);
22630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    }
22640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
226544fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor    // If a method is deprecated, push it in the global pool.
226644fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor    // This is used for better diagnostics.
226744fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor    if (Method->isDeprecated()) {
226844fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor      if (!PrevObjCMethod->isDeprecated())
22690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        List->setMethod(Method);
227044fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor    }
22710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    // If the new method is unavailable, push it into global pool
227244fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor    // unless previous one is deprecated.
227344fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor    if (Method->isUnavailable()) {
227444fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor      if (PrevObjCMethod->getAvailability() < AR_Deprecated)
22750e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        List->setMethod(Method);
227644fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor    }
22770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
2278ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor    return;
227944fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor  }
22800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
228144fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor  // We have a new signature for an existing method - add it.
228244fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor  // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
22835ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor  ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>();
22840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Previous->setNext(new (Mem) ObjCMethodList(Method));
228544fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor}
228644fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor
2287db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl/// \brief Read the contents of the method pool for a given selector from
2288db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl/// external storage.
22895ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregorvoid Sema::ReadMethodPool(Selector Sel) {
2290f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor  assert(ExternalSource && "We need an external AST source");
22915ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor  ExternalSource->ReadMethodPool(Sel);
2292f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor}
2293f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor
2294ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregorvoid Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl,
2295db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl                                 bool instance) {
22969a0b6b4e2bf6a9ef41d32b4e83f2911981d2d44dArgyrios Kyrtzidis  // Ignore methods of invalid containers.
22979a0b6b4e2bf6a9ef41d32b4e83f2911981d2d44dArgyrios Kyrtzidis  if (cast<Decl>(Method->getDeclContext())->isInvalidDecl())
2298ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor    return;
22999a0b6b4e2bf6a9ef41d32b4e83f2911981d2d44dArgyrios Kyrtzidis
23000d266d623452f09d06973528217390d762a8f3faDouglas Gregor  if (ExternalSource)
23010d266d623452f09d06973528217390d762a8f3faDouglas Gregor    ReadMethodPool(Method->getSelector());
23020d266d623452f09d06973528217390d762a8f3faDouglas Gregor
2303db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl  GlobalMethodPool::iterator Pos = MethodPool.find(Method->getSelector());
23040d266d623452f09d06973528217390d762a8f3faDouglas Gregor  if (Pos == MethodPool.end())
23050d266d623452f09d06973528217390d762a8f3faDouglas Gregor    Pos = MethodPool.insert(std::make_pair(Method->getSelector(),
23060d266d623452f09d06973528217390d762a8f3faDouglas Gregor                                           GlobalMethods())).first;
23070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
23083fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian  Method->setDefined(impl);
230944fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor
2310db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl  ObjCMethodList &Entry = instance ? Pos->second.first : Pos->second.second;
2311ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor  addMethodToGlobalList(&Entry, Method);
23124d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
23134d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
2314f85e193739c953358c865005855253af4f68a497John McCall/// Determines if this is an "acceptable" loose mismatch in the global
2315f85e193739c953358c865005855253af4f68a497John McCall/// method pool.  This exists mostly as a hack to get around certain
2316f85e193739c953358c865005855253af4f68a497John McCall/// global mismatches which we can't afford to make warnings / errors.
2317f85e193739c953358c865005855253af4f68a497John McCall/// Really, what we want is a way to take a method out of the global
2318f85e193739c953358c865005855253af4f68a497John McCall/// method pool.
2319f85e193739c953358c865005855253af4f68a497John McCallstatic bool isAcceptableMethodMismatch(ObjCMethodDecl *chosen,
2320f85e193739c953358c865005855253af4f68a497John McCall                                       ObjCMethodDecl *other) {
2321f85e193739c953358c865005855253af4f68a497John McCall  if (!chosen->isInstanceMethod())
2322f85e193739c953358c865005855253af4f68a497John McCall    return false;
2323f85e193739c953358c865005855253af4f68a497John McCall
2324f85e193739c953358c865005855253af4f68a497John McCall  Selector sel = chosen->getSelector();
2325f85e193739c953358c865005855253af4f68a497John McCall  if (!sel.isUnarySelector() || sel.getNameForSlot(0) != "length")
2326f85e193739c953358c865005855253af4f68a497John McCall    return false;
2327f85e193739c953358c865005855253af4f68a497John McCall
2328f85e193739c953358c865005855253af4f68a497John McCall  // Don't complain about mismatches for -length if the method we
2329f85e193739c953358c865005855253af4f68a497John McCall  // chose has an integral result type.
2330651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return (chosen->getReturnType()->isIntegerType());
2331f85e193739c953358c865005855253af4f68a497John McCall}
2332f85e193739c953358c865005855253af4f68a497John McCall
23330e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesbool Sema::CollectMultipleMethodsInGlobalPool(
23340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    Selector Sel, SmallVectorImpl<ObjCMethodDecl *> &Methods, bool instance) {
2335176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (ExternalSource)
2336176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    ReadMethodPool(Sel);
2337176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
2338176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
2339176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (Pos == MethodPool.end())
2340176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return false;
2341176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // Gather the non-hidden methods.
2342176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second;
2343176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  for (ObjCMethodList *M = &MethList; M; M = M->getNext())
23440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    if (M->getMethod() && !M->getMethod()->isHidden())
23450e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      Methods.push_back(M->getMethod());
23460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  return Methods.size() > 1;
2347176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
2348176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
234933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarbool Sema::AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod,
235033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar                                          SourceRange R,
235133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar                                          bool receiverIdOrClass) {
2352176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
23530e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // Test for no method in the pool which should not trigger any warning by
23540e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // caller.
2355176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (Pos == MethodPool.end())
2356176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return true;
235733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  ObjCMethodList &MethList =
235833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar    BestMethod->isInstanceMethod() ? Pos->second.first : Pos->second.second;
235933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar
236033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  // Diagnose finding more than one method in global pool
236133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  SmallVector<ObjCMethodDecl *, 4> Methods;
236233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  Methods.push_back(BestMethod);
236333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  for (ObjCMethodList *M = &MethList; M; M = M->getNext())
236433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar    if (M->getMethod() && !M->getMethod()->isHidden() &&
236533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar        M->getMethod() != BestMethod)
236633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar      Methods.push_back(M->getMethod());
236733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  if (Methods.size() > 1)
236833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar    DiagnoseMultipleMethodInGlobalPool(Methods, Sel, R, receiverIdOrClass);
236933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar
23700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  return MethList.hasMoreThanOneDecl();
2371176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
2372176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
2373db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian RedlObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R,
23746b308f6dc7d8f1581c52095f435c0e1284b111d8Fariborz Jahanian                                               bool receiverIdOrClass,
237533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar                                               bool instance) {
23760d266d623452f09d06973528217390d762a8f3faDouglas Gregor  if (ExternalSource)
23770d266d623452f09d06973528217390d762a8f3faDouglas Gregor    ReadMethodPool(Sel);
23780d266d623452f09d06973528217390d762a8f3faDouglas Gregor
2379db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl  GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
23800d266d623452f09d06973528217390d762a8f3faDouglas Gregor  if (Pos == MethodPool.end())
23816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
2382f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor
2383f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor  // Gather the non-hidden methods.
2384db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl  ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second;
2385e7205c0e2472dd66238f4c6b6db1b7cc2957b42aRobert Wilhelm  SmallVector<ObjCMethodDecl *, 4> Methods;
23862e3d8c0815acaf1bc5995ebe56cea07471e5c9c7Argyrios Kyrtzidis  for (ObjCMethodList *M = &MethList; M; M = M->getNext()) {
238733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar    if (M->getMethod() && !M->getMethod()->isHidden())
238833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar      return M->getMethod();
2389f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor  }
239033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  return nullptr;
239133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar}
23921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
239333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarvoid Sema::DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl*> &Methods,
239433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar                                              Selector Sel, SourceRange R,
239533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar                                              bool receiverIdOrClass) {
2396f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor  // We found multiple methods, so we may have to complain.
2397f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor  bool issueDiagnostic = false, issueError = false;
239833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar
2399f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor  // We support a warning which complains about *any* difference in
2400f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor  // method signature.
2401f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor  bool strictSelectorMatch =
240233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  receiverIdOrClass &&
240333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  !Diags.isIgnored(diag::warn_strict_multiple_method_decl, R.getBegin());
2404f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor  if (strictSelectorMatch) {
2405f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor    for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
2406f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor      if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_strict)) {
2407f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor        issueDiagnostic = true;
2408f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor        break;
24096b308f6dc7d8f1581c52095f435c0e1284b111d8Fariborz Jahanian      }
2410f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor    }
2411f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor  }
241233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar
2413f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor  // If we didn't see any strict differences, we won't see any loose
2414f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor  // differences.  In ARC, however, we also need to check for loose
2415f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor  // mismatches, because most of them are errors.
2416f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor  if (!strictSelectorMatch ||
2417f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor      (issueDiagnostic && getLangOpts().ObjCAutoRefCount))
2418f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor    for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
2419f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor      // This checks if the methods differ in type mismatch.
2420f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor      if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_loose) &&
2421f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor          !isAcceptableMethodMismatch(Methods[0], Methods[I])) {
2422f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor        issueDiagnostic = true;
2423f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor        if (getLangOpts().ObjCAutoRefCount)
2424f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor          issueError = true;
2425f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor        break;
2426f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor      }
24274d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    }
242833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar
2429f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor  if (issueDiagnostic) {
2430f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor    if (issueError)
2431f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor      Diag(R.getBegin(), diag::err_arc_multiple_method_decl) << Sel << R;
2432f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor    else if (strictSelectorMatch)
2433f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor      Diag(R.getBegin(), diag::warn_strict_multiple_method_decl) << Sel << R;
2434f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor    else
2435f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor      Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
243633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar
2437f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor    Diag(Methods[0]->getLocStart(),
2438f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor         issueError ? diag::note_possibility : diag::note_using)
243933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar    << Methods[0]->getSourceRange();
2440f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor    for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
2441f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor      Diag(Methods[I]->getLocStart(), diag::note_also_found)
244233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar      << Methods[I]->getSourceRange();
244333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar    }
2444f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor  }
2445f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor}
2446f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor
24473fe104154dd2e8ffb351142d74f308938b5c99bfFariborz JahanianObjCMethodDecl *Sema::LookupImplementedMethodInGlobalPool(Selector Sel) {
2448db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl  GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
2449db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl  if (Pos == MethodPool.end())
24506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
2451db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl
2452db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl  GlobalMethods &Methods = Pos->second;
2453651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const ObjCMethodList *Method = &Methods.first; Method;
2454651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines       Method = Method->getNext())
24550e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    if (Method->getMethod() &&
24560e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        (Method->getMethod()->isDefined() ||
24570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines         Method->getMethod()->isPropertyAccessor()))
24580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      return Method->getMethod();
2459651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
2460651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const ObjCMethodList *Method = &Methods.second; Method;
2461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines       Method = Method->getNext())
24620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    if (Method->getMethod() &&
24630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines        (Method->getMethod()->isDefined() ||
24640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines         Method->getMethod()->isPropertyAccessor()))
24650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      return Method->getMethod();
24666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
24673fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian}
24683fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian
2469f98c688968777214bfff7a6cc9bbd4ff78e9c1d3Fariborz Jahanianstatic void
24709464a08a743295d6aefaca1a751b5b4d371cf99cFariborz JahanianHelperSelectorsForTypoCorrection(
24719464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian                      SmallVectorImpl<const ObjCMethodDecl *> &BestMethod,
24729464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian                      StringRef Typo, const ObjCMethodDecl * Method) {
24739464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian  const unsigned MaxEditDistance = 1;
24749464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian  unsigned BestEditDistance = MaxEditDistance + 1;
24754fe9644dc3533e4517f980645957c6fc9408c6f6Richard Trieu  std::string MethodName = Method->getSelector().getAsString();
24769464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian
24779464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian  unsigned MinPossibleEditDistance = abs((int)MethodName.size() - (int)Typo.size());
24789464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian  if (MinPossibleEditDistance > 0 &&
24799464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian      Typo.size() / MinPossibleEditDistance < 1)
24809464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian    return;
24819464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian  unsigned EditDistance = Typo.edit_distance(MethodName, true, MaxEditDistance);
24829464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian  if (EditDistance > MaxEditDistance)
24839464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian    return;
24849464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian  if (EditDistance == BestEditDistance)
24859464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian    BestMethod.push_back(Method);
24869464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian  else if (EditDistance < BestEditDistance) {
24879464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian    BestMethod.clear();
24889464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian    BestMethod.push_back(Method);
24899464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian  }
24909464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian}
24919464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian
2492d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanianstatic bool HelperIsMethodInObjCType(Sema &S, Selector Sel,
2493d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian                                     QualType ObjectType) {
2494d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian  if (ObjectType.isNull())
2495d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian    return true;
2496d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian  if (S.LookupMethodInObjectType(Sel, ObjectType, true/*Instance method*/))
2497d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian    return true;
24986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return S.LookupMethodInObjectType(Sel, ObjectType, false/*Class method*/) !=
24996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines         nullptr;
2500d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian}
2501d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian
25029464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanianconst ObjCMethodDecl *
2503d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz JahanianSema::SelectorsForTypoCorrection(Selector Sel,
2504d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian                                 QualType ObjectType) {
25059464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian  unsigned NumArgs = Sel.getNumArgs();
25069464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian  SmallVector<const ObjCMethodDecl *, 8> Methods;
2507419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian  bool ObjectIsId = true, ObjectIsClass = true;
2508419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian  if (ObjectType.isNull())
2509419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian    ObjectIsId = ObjectIsClass = false;
2510419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian  else if (!ObjectType->isObjCObjectPointerType())
25116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
2512419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian  else if (const ObjCObjectPointerType *ObjCPtr =
2513419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian           ObjectType->getAsObjCInterfacePointerType()) {
2514419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian    ObjectType = QualType(ObjCPtr->getInterfaceType(), 0);
2515419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian    ObjectIsId = ObjectIsClass = false;
2516419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian  }
2517419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian  else if (ObjectType->isObjCIdType() || ObjectType->isObjCQualifiedIdType())
2518419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian    ObjectIsClass = false;
2519419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian  else if (ObjectType->isObjCClassType() || ObjectType->isObjCQualifiedClassType())
2520419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian    ObjectIsId = false;
2521419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian  else
25226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
25236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
25249464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian  for (GlobalMethodPool::iterator b = MethodPool.begin(),
25259464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian       e = MethodPool.end(); b != e; b++) {
25269464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian    // instance methods
25279464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian    for (ObjCMethodList *M = &b->second.first; M; M=M->getNext())
25280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      if (M->getMethod() &&
25290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines          (M->getMethod()->getSelector().getNumArgs() == NumArgs) &&
25300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines          (M->getMethod()->getSelector() != Sel)) {
2531419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian        if (ObjectIsId)
25320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines          Methods.push_back(M->getMethod());
2533419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian        else if (!ObjectIsClass &&
25340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                 HelperIsMethodInObjCType(*this, M->getMethod()->getSelector(),
25350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                          ObjectType))
25360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines          Methods.push_back(M->getMethod());
2537419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian      }
25389464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian    // class methods
25399464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian    for (ObjCMethodList *M = &b->second.second; M; M=M->getNext())
25400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      if (M->getMethod() &&
25410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines          (M->getMethod()->getSelector().getNumArgs() == NumArgs) &&
25420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines          (M->getMethod()->getSelector() != Sel)) {
2543419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian        if (ObjectIsClass)
25440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines          Methods.push_back(M->getMethod());
2545419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian        else if (!ObjectIsId &&
25460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                 HelperIsMethodInObjCType(*this, M->getMethod()->getSelector(),
25470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                          ObjectType))
25480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines          Methods.push_back(M->getMethod());
2549419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian      }
25509464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian  }
25519464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian
25529464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian  SmallVector<const ObjCMethodDecl *, 8> SelectedMethods;
25539464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian  for (unsigned i = 0, e = Methods.size(); i < e; i++) {
25549464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian    HelperSelectorsForTypoCorrection(SelectedMethods,
25559464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian                                     Sel.getAsString(), Methods[i]);
25569464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian  }
25576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return (SelectedMethods.size() == 1) ? SelectedMethods[0] : nullptr;
25589464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian}
25599464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian
2560f98c688968777214bfff7a6cc9bbd4ff78e9c1d3Fariborz Jahanian/// DiagnoseDuplicateIvars -
2561f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian/// Check for duplicate ivars in the entire class at the start of
25621dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// \@implementation. This becomes necesssary because class extension can
2563f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian/// add ivars to a class in random order which will not be known until
25641dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// class's \@implementation is seen.
2565f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanianvoid Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID,
2566f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian                                  ObjCInterfaceDecl *SID) {
2567651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *Ivar : ID->ivars()) {
2568f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian    if (Ivar->isInvalidDecl())
2569f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian      continue;
2570f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian    if (IdentifierInfo *II = Ivar->getIdentifier()) {
2571f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian      ObjCIvarDecl* prevIvar = SID->lookupInstanceVariable(II);
2572f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian      if (prevIvar) {
2573f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian        Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;
2574f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian        Diag(prevIvar->getLocation(), diag::note_previous_declaration);
2575f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian        Ivar->setInvalidDecl();
2576f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian      }
2577f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian    }
2578f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian  }
2579f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian}
2580f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian
2581d64251fd56577dd5c78903454632361e094c6dc1Erik VerbruggenSema::ObjCContainerKind Sema::getObjCContainerKind() const {
2582d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen  switch (CurContext->getDeclKind()) {
2583d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen    case Decl::ObjCInterface:
2584d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen      return Sema::OCK_Interface;
2585d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen    case Decl::ObjCProtocol:
2586d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen      return Sema::OCK_Protocol;
2587d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen    case Decl::ObjCCategory:
258833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar      if (cast<ObjCCategoryDecl>(CurContext)->IsClassExtension())
2589d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen        return Sema::OCK_ClassExtension;
259033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar      return Sema::OCK_Category;
2591d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen    case Decl::ObjCImplementation:
2592d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen      return Sema::OCK_Implementation;
2593d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen    case Decl::ObjCCategoryImpl:
2594d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen      return Sema::OCK_CategoryImplementation;
2595d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen
2596d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen    default:
2597d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen      return Sema::OCK_None;
2598d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen  }
2599d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen}
2600d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen
2601a3c6246950f23d7d4cd748badaf8f05d7bc3f14aFariborz Jahanian// Note: For class/category implementations, allMethods is always null.
26020111e4da0133c7fb4815e5c60524d2aaddfbccf0Robert WilhelmDecl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods,
260380f8aca7aeac5be1c9c33813c2afcab6538199aaFariborz Jahanian                       ArrayRef<DeclGroupPtrTy> allTUVars) {
2604d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen  if (getObjCContainerKind() == Sema::OCK_None)
26056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
2606d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen
2607d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen  assert(AtEnd.isValid() && "Invalid location for '@end'");
2608a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian
2609a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian  ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
2610a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian  Decl *ClassDecl = cast<Decl>(OCD);
261163e963cdffca9530f920dbab58b9b4eecb2a582cFariborz Jahanian
26121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool isInterfaceDeclKind =
2613f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner        isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl)
2614f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner         || isa<ObjCProtocolDecl>(ClassDecl);
2615a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl);
261609c4719788a5cea09897525e528fa00420f1677bSteve Naroff
26170701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  // FIXME: Remove these and use the ObjCContainerDecl/DeclContext.
26180701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;
26190701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;
26200701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff
2621a3c6246950f23d7d4cd748badaf8f05d7bc3f14aFariborz Jahanian  for (unsigned i = 0, e = allMethods.size(); i != e; i++ ) {
2622a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    ObjCMethodDecl *Method =
2623d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall      cast_or_null<ObjCMethodDecl>(allMethods[i]);
26244d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
26254d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    if (!Method) continue;  // Already issued a diagnostic.
2626f8d49f64ef6ab7e632717a31631fc289aab69428Douglas Gregor    if (Method->isInstanceMethod()) {
26274d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner      /// Check for instance method of the same name with incompatible types
2628a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      const ObjCMethodDecl *&PrevMethod = InsMap[Method->getSelector()];
26291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
26304d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner                              : false;
26311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      if ((isInterfaceDeclKind && PrevMethod && !match)
263282b4e768d38c12ceba7db23a96e8d845e00fdeb7Eli Friedman          || (checkIdenticalMethods && match)) {
26335f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner          Diag(Method->getLocation(), diag::err_duplicate_method_decl)
2634077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner            << Method->getDeclName();
26355f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner          Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
2636bdb2d5056fd675c27307b34efd371bbba6839e92Douglas Gregor        Method->setInvalidDecl();
26374d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner      } else {
26387209646add692c50503435bcffb13187a3349552Fariborz Jahanian        if (PrevMethod) {
26393a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis          Method->setAsRedeclaration(PrevMethod);
26407209646add692c50503435bcffb13187a3349552Fariborz Jahanian          if (!Context.getSourceManager().isInSystemHeader(
26417209646add692c50503435bcffb13187a3349552Fariborz Jahanian                 Method->getLocation()))
26427209646add692c50503435bcffb13187a3349552Fariborz Jahanian            Diag(Method->getLocation(), diag::warn_duplicate_method_decl)
26437209646add692c50503435bcffb13187a3349552Fariborz Jahanian              << Method->getDeclName();
26447209646add692c50503435bcffb13187a3349552Fariborz Jahanian          Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
26457209646add692c50503435bcffb13187a3349552Fariborz Jahanian        }
26464d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner        InsMap[Method->getSelector()] = Method;
26474d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner        /// The following allows us to typecheck messages to "id".
2648ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor        AddInstanceMethodToGlobalPool(Method);
26494d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner      }
2650ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump    } else {
26514d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner      /// Check for class method of the same name with incompatible types
2652a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      const ObjCMethodDecl *&PrevMethod = ClsMap[Method->getSelector()];
26531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
26544d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner                              : false;
26551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      if ((isInterfaceDeclKind && PrevMethod && !match)
265682b4e768d38c12ceba7db23a96e8d845e00fdeb7Eli Friedman          || (checkIdenticalMethods && match)) {
26575f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner        Diag(Method->getLocation(), diag::err_duplicate_method_decl)
2658077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner          << Method->getDeclName();
26595f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner        Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
2660bdb2d5056fd675c27307b34efd371bbba6839e92Douglas Gregor        Method->setInvalidDecl();
26614d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner      } else {
26627209646add692c50503435bcffb13187a3349552Fariborz Jahanian        if (PrevMethod) {
26633a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis          Method->setAsRedeclaration(PrevMethod);
26647209646add692c50503435bcffb13187a3349552Fariborz Jahanian          if (!Context.getSourceManager().isInSystemHeader(
26657209646add692c50503435bcffb13187a3349552Fariborz Jahanian                 Method->getLocation()))
26667209646add692c50503435bcffb13187a3349552Fariborz Jahanian            Diag(Method->getLocation(), diag::warn_duplicate_method_decl)
26677209646add692c50503435bcffb13187a3349552Fariborz Jahanian              << Method->getDeclName();
26687209646add692c50503435bcffb13187a3349552Fariborz Jahanian          Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
26697209646add692c50503435bcffb13187a3349552Fariborz Jahanian        }
26704d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner        ClsMap[Method->getSelector()] = Method;
2671ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor        AddFactoryMethodToGlobalPool(Method);
26724d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner      }
26734d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    }
26744d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
2675b892d7010f9c2c61e2f3a2686546cbfbffbedef3Douglas Gregor  if (isa<ObjCInterfaceDecl>(ClassDecl)) {
2676b892d7010f9c2c61e2f3a2686546cbfbffbedef3Douglas Gregor    // Nothing to do here.
267709c4719788a5cea09897525e528fa00420f1677bSteve Naroff  } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
267877e14bd3a714be42dbe1ab90a37b5832740b6df2Fariborz Jahanian    // Categories are used to extend the class by declaring new methods.
26791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // By the same token, they are also used to add new properties. No
268077e14bd3a714be42dbe1ab90a37b5832740b6df2Fariborz Jahanian    // need to compare the added property to those in the class.
2681b20ef3e3fbe0fabe213dc0149011e9f0d751a3a4Daniel Dunbar
268288f5e9be350f4b107f8665183a6d441874e0fcc7Fariborz Jahanian    if (C->IsClassExtension()) {
268388f5e9be350f4b107f8665183a6d441874e0fcc7Fariborz Jahanian      ObjCInterfaceDecl *CCPrimary = C->getClassInterface();
268488f5e9be350f4b107f8665183a6d441874e0fcc7Fariborz Jahanian      DiagnoseClassExtensionDupMethods(C, CCPrimary);
268588f5e9be350f4b107f8665183a6d441874e0fcc7Fariborz Jahanian    }
26864d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
268709c4719788a5cea09897525e528fa00420f1677bSteve Naroff  if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(ClassDecl)) {
268825760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian    if (CDecl->getIdentifier())
268925760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian      // ProcessPropertyDecl is responsible for diagnosing conflicts with any
269025760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian      // user-defined setter/getter. It also synthesizes setter/getter methods
269125760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian      // and adds them to the DeclContext and global method pools.
2692651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      for (auto *I : CDecl->properties())
2693651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        ProcessPropertyDecl(I, CDecl);
2694782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek    CDecl->setAtEndRange(AtEnd);
269509c4719788a5cea09897525e528fa00420f1677bSteve Naroff  }
269609c4719788a5cea09897525e528fa00420f1677bSteve Naroff  if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
2697782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek    IC->setAtEndRange(AtEnd);
26987ca8b0694840385d707689eba9ad965e7b28c8cbFariborz Jahanian    if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) {
2699c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian      // Any property declared in a class extension might have user
2700c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian      // declared setter or getter in current class extension or one
2701c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian      // of the other class extensions. Mark them as synthesized as
2702c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian      // property will be synthesized when property with same name is
2703c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian      // seen in the @implementation.
2704651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      for (const auto *Ext : IDecl->visible_extensions()) {
2705651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        for (const auto *Property : Ext->properties()) {
2706c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian          // Skip over properties declared @dynamic
2707c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian          if (const ObjCPropertyImplDecl *PIDecl
2708c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian              = IC->FindPropertyImplDecl(Property->getIdentifier()))
2709c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian            if (PIDecl->getPropertyImplementation()
2710c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian                  == ObjCPropertyImplDecl::Dynamic)
2711c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian              continue;
2712d329724745b49f894b768d47275b7c2713106e89Douglas Gregor
2713651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          for (const auto *Ext : IDecl->visible_extensions()) {
2714d329724745b49f894b768d47275b7c2713106e89Douglas Gregor            if (ObjCMethodDecl *GetterMethod
2715d329724745b49f894b768d47275b7c2713106e89Douglas Gregor                  = Ext->getInstanceMethod(Property->getGetterName()))
27161e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose              GetterMethod->setPropertyAccessor(true);
2717c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian            if (!Property->isReadOnly())
2718d329724745b49f894b768d47275b7c2713106e89Douglas Gregor              if (ObjCMethodDecl *SetterMethod
2719d329724745b49f894b768d47275b7c2713106e89Douglas Gregor                    = Ext->getInstanceMethod(Property->getSetterName()))
27201e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose                SetterMethod->setPropertyAccessor(true);
2721d329724745b49f894b768d47275b7c2713106e89Douglas Gregor          }
2722c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian        }
2723c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian      }
272417cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian      ImplMethodsVsClassMethods(S, IC, IDecl);
27257ca8b0694840385d707689eba9ad965e7b28c8cbFariborz Jahanian      AtomicPropertySetterGetterRules(IC, IDecl);
2726f85e193739c953358c865005855253af4f68a497John McCall      DiagnoseOwningPropertyGetterSynthesis(IC);
2727651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      DiagnoseUnusedBackingIvarInAccessor(S, IC);
2728651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (IDecl->hasDesignatedInitializers())
2729651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        DiagnoseMissingDesignatedInitOverrides(IC, IDecl);
2730651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
2731b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard      bool HasRootClassAttr = IDecl->hasAttr<ObjCRootClassAttr>();
27326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (IDecl->getSuperClass() == nullptr) {
2733b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard        // This class has no superclass, so check that it has been marked with
2734b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard        // __attribute((objc_root_class)).
2735b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard        if (!HasRootClassAttr) {
2736b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard          SourceLocation DeclLoc(IDecl->getLocation());
27376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          SourceLocation SuperClassLoc(getLocForEndOfToken(DeclLoc));
2738b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard          Diag(DeclLoc, diag::warn_objc_root_class_missing)
2739b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard            << IDecl->getIdentifier();
2740b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard          // See if NSObject is in the current scope, and if it is, suggest
2741b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard          // adding " : NSObject " to the class declaration.
2742b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard          NamedDecl *IF = LookupSingleName(TUScope,
2743b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard                                           NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject),
2744b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard                                           DeclLoc, LookupOrdinaryName);
2745b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard          ObjCInterfaceDecl *NSObjectDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
2746b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard          if (NSObjectDecl && NSObjectDecl->getDefinition()) {
2747b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard            Diag(SuperClassLoc, diag::note_objc_needs_superclass)
2748b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard              << FixItHint::CreateInsertion(SuperClassLoc, " : NSObject ");
2749b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard          } else {
2750b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard            Diag(SuperClassLoc, diag::note_objc_needs_superclass);
2751b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard          }
2752b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard        }
2753b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard      } else if (HasRootClassAttr) {
2754b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard        // Complain that only root classes may have this attribute.
2755b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard        Diag(IDecl->getLocation(), diag::err_objc_root_class_subclass);
2756b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard      }
2757b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard
2758260611a32535c851237926bfcf78869b13c07d5bJohn McCall      if (LangOpts.ObjCRuntime.isNonFragile()) {
2759f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian        while (IDecl->getSuperClass()) {
2760f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian          DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass());
2761f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian          IDecl = IDecl->getSuperClass();
2762f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian        }
2763b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard      }
27647ca8b0694840385d707689eba9ad965e7b28c8cbFariborz Jahanian    }
2765e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian    SetIvarInitializers(IC);
27661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  } else if (ObjCCategoryImplDecl* CatImplClass =
276709c4719788a5cea09897525e528fa00420f1677bSteve Naroff                                   dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
2768782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek    CatImplClass->setAtEndRange(AtEnd);
27691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
27704d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    // Find category interface decl and then check that all methods declared
2771b20ef3e3fbe0fabe213dc0149011e9f0d751a3a4Daniel Dunbar    // in this interface are implemented in the category @implementation.
277297a588715d6c896158106d6ca732196d3fee857bChris Lattner    if (ObjCInterfaceDecl* IDecl = CatImplClass->getClassInterface()) {
2773d329724745b49f894b768d47275b7c2713106e89Douglas Gregor      if (ObjCCategoryDecl *Cat
2774d329724745b49f894b768d47275b7c2713106e89Douglas Gregor            = IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier())) {
2775d329724745b49f894b768d47275b7c2713106e89Douglas Gregor        ImplMethodsVsClassMethods(S, CatImplClass, Cat);
27764d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner      }
27774d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    }
27784d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
2779682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  if (isInterfaceDeclKind) {
2780682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    // Reject invalid vardecls.
2781a3c6246950f23d7d4cd748badaf8f05d7bc3f14aFariborz Jahanian    for (unsigned i = 0, e = allTUVars.size(); i != e; i++) {
278218062394db459158942ab491a88b9d52a5c0ab0dSerge Pavlov      DeclGroupRef DG = allTUVars[i].get();
2783682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
2784682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        if (VarDecl *VDecl = dyn_cast<VarDecl>(*I)) {
27855466c7b0ca8ce662e2c0bc295cecba2b78d6957dDaniel Dunbar          if (!VDecl->hasExternalStorage())
278687454161a6377b573d4fc3ff45e7b3ec193e860cSteve Naroff            Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass);
2787b31cb7f1752ea011fd06ac9574ce24667d11cbdbFariborz Jahanian        }
2788682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    }
278938e24c782c17b6058bf61d635747bbde19fb1bc7Fariborz Jahanian  }
279010af87932fe4bffad539b24d512a33a1803daeaeFariborz Jahanian  ActOnObjCContainerFinishDefinition();
2791b4a686df4de21ec4eeca69211b21f7fe716abeaeArgyrios Kyrtzidis
2792a3c6246950f23d7d4cd748badaf8f05d7bc3f14aFariborz Jahanian  for (unsigned i = 0, e = allTUVars.size(); i != e; i++) {
279318062394db459158942ab491a88b9d52a5c0ab0dSerge Pavlov    DeclGroupRef DG = allTUVars[i].get();
2794c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis    for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
2795c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis      (*I)->setTopLevelDeclInObjCContainer();
2796b4a686df4de21ec4eeca69211b21f7fe716abeaeArgyrios Kyrtzidis    Consumer.HandleTopLevelDeclInObjCContainer(DG);
2797b4a686df4de21ec4eeca69211b21f7fe716abeaeArgyrios Kyrtzidis  }
2798d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen
2799abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko  ActOnDocumentableDecl(ClassDecl);
2800d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen  return ClassDecl;
28014d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
28024d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
28034d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
28044d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// CvtQTToAstBitMask - utility routine to produce an AST bitmask for
28054d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// objective-c's type qualifier from the parser version of the same info.
28061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic Decl::ObjCDeclQualifier
2807a526c5c67e5a0473c340903ee542ce570119665fTed KremenekCvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) {
280809e2c524a18435211cfbc2fb355f91e1ac43ea89John McCall  return (Decl::ObjCDeclQualifier) (unsigned) PQTVal;
28094d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
28104d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
2811926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor/// \brief Check whether the declared result type of the given Objective-C
2812926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor/// method declaration is compatible with the method's class.
2813926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor///
2814e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidisstatic Sema::ResultTypeCompatibilityKind
2815926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas GregorCheckRelatedResultTypeCompatibility(Sema &S, ObjCMethodDecl *Method,
2816926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                    ObjCInterfaceDecl *CurrentClass) {
2817651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  QualType ResultType = Method->getReturnType();
2818651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
2819926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  // If an Objective-C method inherits its related result type, then its
2820926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  // declared result type must be compatible with its own class type. The
2821926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  // declared result type is compatible if:
2822926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  if (const ObjCObjectPointerType *ResultObjectType
2823926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                = ResultType->getAs<ObjCObjectPointerType>()) {
2824926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    //   - it is id or qualified id, or
2825926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    if (ResultObjectType->isObjCIdType() ||
2826926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor        ResultObjectType->isObjCQualifiedIdType())
2827e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis      return Sema::RTC_Compatible;
2828926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
2829926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    if (CurrentClass) {
2830926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      if (ObjCInterfaceDecl *ResultClass
2831926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                      = ResultObjectType->getInterfaceDecl()) {
2832926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor        //   - it is the same as the method's class type, or
283360ef308e51c71b760d7f598c1b763ceb7b768148Douglas Gregor        if (declaresSameEntity(CurrentClass, ResultClass))
2834e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis          return Sema::RTC_Compatible;
2835926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
2836926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor        //   - it is a superclass of the method's class type
2837926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor        if (ResultClass->isSuperClassOf(CurrentClass))
2838e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis          return Sema::RTC_Compatible;
2839926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      }
2840e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor    } else {
2841e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor      // Any Objective-C pointer type might be acceptable for a protocol
2842e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor      // method; we just don't know.
2843e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis      return Sema::RTC_Unknown;
2844926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    }
2845926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  }
2846926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
2847e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  return Sema::RTC_Incompatible;
2848926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor}
2849926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
28506c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCallnamespace {
28516c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall/// A helper class for searching for methods which a particular method
28526c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall/// overrides.
28536c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCallclass OverrideSearch {
2854b732fcebcf2ce5c24a29d660e9400d7dc9f86b69Daniel Dunbarpublic:
28556c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  Sema &S;
28566c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  ObjCMethodDecl *Method;
2857b732fcebcf2ce5c24a29d660e9400d7dc9f86b69Daniel Dunbar  llvm::SmallPtrSet<ObjCMethodDecl*, 4> Overridden;
28586c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  bool Recursive;
28596c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
28606c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCallpublic:
28616c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  OverrideSearch(Sema &S, ObjCMethodDecl *method) : S(S), Method(method) {
28626c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    Selector selector = method->getSelector();
28636c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
28646c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // Bypass this search if we've never seen an instance/class method
28656c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // with this selector before.
28666c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    Sema::GlobalMethodPool::iterator it = S.MethodPool.find(selector);
28676c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    if (it == S.MethodPool.end()) {
28680ec56b7add7be643f490ea9b430823570f01b4e2Axel Naumann      if (!S.getExternalSource()) return;
28695ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor      S.ReadMethodPool(selector);
28705ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor
28715ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor      it = S.MethodPool.find(selector);
28725ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor      if (it == S.MethodPool.end())
28735ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor        return;
28746c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    }
28756c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    ObjCMethodList &list =
28766c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall      method->isInstanceMethod() ? it->second.first : it->second.second;
28770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    if (!list.getMethod()) return;
28786c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
28796c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    ObjCContainerDecl *container
28806c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall      = cast<ObjCContainerDecl>(method->getDeclContext());
28816c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
28826c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // Prevent the search from reaching this container again.  This is
28836c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // important with categories, which override methods from the
28846c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // interface and each other.
2885c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor    if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(container)) {
2886c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor      searchFromContainer(container);
2887dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor      if (ObjCInterfaceDecl *Interface = Category->getClassInterface())
2888dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor        searchFromContainer(Interface);
2889c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor    } else {
2890c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor      searchFromContainer(container);
2891c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor    }
2892926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  }
28936c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
2894b732fcebcf2ce5c24a29d660e9400d7dc9f86b69Daniel Dunbar  typedef llvm::SmallPtrSet<ObjCMethodDecl*, 128>::iterator iterator;
28956c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  iterator begin() const { return Overridden.begin(); }
28966c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  iterator end() const { return Overridden.end(); }
28976c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
28986c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCallprivate:
28996c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  void searchFromContainer(ObjCContainerDecl *container) {
29006c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    if (container->isInvalidDecl()) return;
29016c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
29026c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    switch (container->getDeclKind()) {
29036c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall#define OBJCCONTAINER(type, base) \
29046c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    case Decl::type: \
29056c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall      searchFrom(cast<type##Decl>(container)); \
29066c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall      break;
29076c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall#define ABSTRACT_DECL(expansion)
29086c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall#define DECL(type, base) \
29096c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    case Decl::type:
29106c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall#include "clang/AST/DeclNodes.inc"
29116c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall      llvm_unreachable("not an ObjC container!");
29126c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    }
29136c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  }
29146c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
29156c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  void searchFrom(ObjCProtocolDecl *protocol) {
29165e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor    if (!protocol->hasDefinition())
29175e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor      return;
29185e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor
29196c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // A method in a protocol declaration overrides declarations from
29206c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // referenced ("parent") protocols.
29216c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    search(protocol->getReferencedProtocols());
29226c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  }
29236c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
29246c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  void searchFrom(ObjCCategoryDecl *category) {
29256c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // A method in a category declaration overrides declarations from
29266c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // the main class and from protocols the category references.
2927c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor    // The main class is handled in the constructor.
29286c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    search(category->getReferencedProtocols());
29296c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  }
29306c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
29316c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  void searchFrom(ObjCCategoryImplDecl *impl) {
29326c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // A method in a category definition that has a category
29336c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // declaration overrides declarations from the category
29346c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // declaration.
29356c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    if (ObjCCategoryDecl *category = impl->getCategoryDecl()) {
29366c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall      search(category);
2937dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor      if (ObjCInterfaceDecl *Interface = category->getClassInterface())
2938dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor        search(Interface);
29396c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
29406c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // Otherwise it overrides declarations from the class.
2941dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor    } else if (ObjCInterfaceDecl *Interface = impl->getClassInterface()) {
2942dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor      search(Interface);
29436c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    }
29446c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  }
29456c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
29466c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  void searchFrom(ObjCInterfaceDecl *iface) {
29476c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // A method in a class declaration overrides declarations from
29482e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor    if (!iface->hasDefinition())
29492e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor      return;
29502e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor
29516c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    //   - categories,
2952651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (auto *Cat : iface->known_categories())
2953651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      search(Cat);
29546c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
29556c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    //   - the super class, and
29566c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    if (ObjCInterfaceDecl *super = iface->getSuperClass())
29576c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall      search(super);
29586c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
29596c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    //   - any referenced protocols.
29606c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    search(iface->getReferencedProtocols());
29616c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  }
29626c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
29636c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  void searchFrom(ObjCImplementationDecl *impl) {
29646c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // A method in a class implementation overrides declarations from
29656c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // the class interface.
2966dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor    if (ObjCInterfaceDecl *Interface = impl->getClassInterface())
2967dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor      search(Interface);
29686c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  }
29696c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
29706c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
29716c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  void search(const ObjCProtocolList &protocols) {
29726c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    for (ObjCProtocolList::iterator i = protocols.begin(), e = protocols.end();
29736c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall         i != e; ++i)
29746c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall      search(*i);
29756c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  }
29766c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
29776c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  void search(ObjCContainerDecl *container) {
29786c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // Check for a method in this container which matches this selector.
29796c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    ObjCMethodDecl *meth = container->getMethod(Method->getSelector(),
298004593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis                                                Method->isInstanceMethod(),
298104593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis                                                /*AllowHidden=*/true);
29826c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
29836c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // If we find one, record it and bail out.
29846c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    if (meth) {
29856c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall      Overridden.insert(meth);
29866c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall      return;
29876c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    }
29886c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
29896c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // Otherwise, search for methods that a hypothetical method here
29906c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // would have overridden.
29916c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
29926c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    // Note that we're now in a recursive case.
29936c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    Recursive = true;
29946c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
29956c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall    searchFromContainer(container);
29966c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  }
29976c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall};
2998926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor}
2999926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
3000e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidisvoid Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod,
3001e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis                                    ObjCInterfaceDecl *CurrentClass,
3002e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis                                    ResultTypeCompatibilityKind RTC) {
3003e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  // Search for overridden methods and merge information down from them.
3004e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  OverrideSearch overrides(*this, ObjCMethod);
3005e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  // Keep track if the method overrides any method in the class's base classes,
3006e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  // its protocols, or its categories' protocols; we will keep that info
3007e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  // in the ObjCMethodDecl.
3008e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  // For this info, a method in an implementation is not considered as
3009e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  // overriding the same method in the interface or its categories.
3010e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  bool hasOverriddenMethodsInBaseOrProtocol = false;
3011e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  for (OverrideSearch::iterator
3012e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis         i = overrides.begin(), e = overrides.end(); i != e; ++i) {
3013e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis    ObjCMethodDecl *overridden = *i;
3014e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis
3015e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis    if (!hasOverriddenMethodsInBaseOrProtocol) {
3016e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis      if (isa<ObjCProtocolDecl>(overridden->getDeclContext()) ||
3017e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis          CurrentClass != overridden->getClassInterface() ||
3018e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis          overridden->isOverriding()) {
3019e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis        hasOverriddenMethodsInBaseOrProtocol = true;
3020e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis
3021e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis      } else if (isa<ObjCImplDecl>(ObjCMethod->getDeclContext())) {
3022e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis        // OverrideSearch will return as "overridden" the same method in the
3023e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis        // interface. For hasOverriddenMethodsInBaseOrProtocol, we need to
3024e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis        // check whether a category of a base class introduced a method with the
3025e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis        // same selector, after the interface method declaration.
3026e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis        // To avoid unnecessary lookups in the majority of cases, we use the
3027e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis        // extra info bits in GlobalMethodPool to check whether there were any
3028e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis        // category methods with this selector.
3029e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis        GlobalMethodPool::iterator It =
3030e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis            MethodPool.find(ObjCMethod->getSelector());
3031e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis        if (It != MethodPool.end()) {
3032e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis          ObjCMethodList &List =
3033e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis            ObjCMethod->isInstanceMethod()? It->second.first: It->second.second;
3034e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis          unsigned CategCount = List.getBits();
3035e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis          if (CategCount > 0) {
3036e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis            // If the method is in a category we'll do lookup if there were at
3037e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis            // least 2 category methods recorded, otherwise only one will do.
3038e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis            if (CategCount > 1 ||
3039e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis                !isa<ObjCCategoryImplDecl>(overridden->getDeclContext())) {
3040e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis              OverrideSearch overrides(*this, overridden);
3041e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis              for (OverrideSearch::iterator
3042e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis                     OI= overrides.begin(), OE= overrides.end(); OI!=OE; ++OI) {
3043e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis                ObjCMethodDecl *SuperOverridden = *OI;
3044ab3d509bc45218c278454962ff644bb13d18ce1aArgyrios Kyrtzidis                if (isa<ObjCProtocolDecl>(SuperOverridden->getDeclContext()) ||
3045ab3d509bc45218c278454962ff644bb13d18ce1aArgyrios Kyrtzidis                    CurrentClass != SuperOverridden->getClassInterface()) {
3046e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis                  hasOverriddenMethodsInBaseOrProtocol = true;
3047e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis                  overridden->setOverriding(true);
3048e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis                  break;
3049e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis                }
3050e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis              }
3051e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis            }
3052e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis          }
3053e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis        }
3054e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis      }
3055e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis    }
3056e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis
3057e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis    // Propagate down the 'related result type' bit from overridden methods.
3058e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis    if (RTC != Sema::RTC_Incompatible && overridden->hasRelatedResultType())
3059e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis      ObjCMethod->SetRelatedResultType();
3060e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis
3061e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis    // Then merge the declarations.
3062e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis    mergeObjCMethodDecls(ObjCMethod, overridden);
3063e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis
3064e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis    if (ObjCMethod->isImplicit() && overridden->isImplicit())
3065e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis      continue; // Conflicting properties are detected elsewhere.
3066e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis
3067e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis    // Check for overriding methods
3068e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis    if (isa<ObjCInterfaceDecl>(ObjCMethod->getDeclContext()) ||
3069e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis        isa<ObjCImplementationDecl>(ObjCMethod->getDeclContext()))
3070e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis      CheckConflictingOverridingMethod(ObjCMethod, overridden,
3071e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis              isa<ObjCProtocolDecl>(overridden->getDeclContext()));
3072e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis
3073e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis    if (CurrentClass && overridden->getDeclContext() != CurrentClass &&
3074c4133a477389dacb4479a96ee2227b92aea0a237Fariborz Jahanian        isa<ObjCInterfaceDecl>(overridden->getDeclContext()) &&
3075c4133a477389dacb4479a96ee2227b92aea0a237Fariborz Jahanian        !overridden->isImplicit() /* not meant for properties */) {
3076e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis      ObjCMethodDecl::param_iterator ParamI = ObjCMethod->param_begin(),
3077e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis                                          E = ObjCMethod->param_end();
30780a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor      ObjCMethodDecl::param_iterator PrevI = overridden->param_begin(),
30790a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor                                     PrevE = overridden->param_end();
30800a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor      for (; ParamI != E && PrevI != PrevE; ++ParamI, ++PrevI) {
3081e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis        assert(PrevI != overridden->param_end() && "Param mismatch");
3082e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis        QualType T1 = Context.getCanonicalType((*ParamI)->getType());
3083e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis        QualType T2 = Context.getCanonicalType((*PrevI)->getType());
3084e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis        // If type of argument of method in this class does not match its
3085e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis        // respective argument type in the super class method, issue warning;
3086e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis        if (!Context.typesAreCompatible(T1, T2)) {
3087e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis          Diag((*ParamI)->getLocation(), diag::ext_typecheck_base_super)
3088e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis            << T1 << T2;
3089e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis          Diag(overridden->getLocation(), diag::note_previous_declaration);
3090e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis          break;
3091e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis        }
3092e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis      }
3093e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis    }
3094e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  }
3095e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis
3096e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  ObjCMethod->setOverriding(hasOverriddenMethodsInBaseOrProtocol);
3097e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis}
3098e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis
3099d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema::ActOnMethodDeclaration(
31007f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian    Scope *S,
31014d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    SourceLocation MethodLoc, SourceLocation EndLoc,
3102a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian    tok::TokenKind MethodType,
3103b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
310411d77169555480ee0a04c6e5bc390d8fde41175dArgyrios Kyrtzidis    ArrayRef<SourceLocation> SelectorLocs,
31054d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    Selector Sel,
31064d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    // optional arguments. The number of types/arguments is obtained
31074d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    // from the Sel.getNumArgs().
3108e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner    ObjCArgInfo *ArgInfo,
31094f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian    DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
31104d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
311190ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian    bool isVariadic, bool MethodDefinition) {
3112da323adbb99cee19a203ead852d5d9bfebb23fb7Steve Naroff  // Make sure we can establish a context for the method.
3113a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian  if (!CurContext->isObjCContainer()) {
3114da323adbb99cee19a203ead852d5d9bfebb23fb7Steve Naroff    Diag(MethodLoc, diag::error_missing_method_context);
31156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
3116da323adbb99cee19a203ead852d5d9bfebb23fb7Steve Naroff  }
3117a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian  ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
3118a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian  Decl *ClassDecl = cast<Decl>(OCD);
31190ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner  QualType resultDeclType;
31201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3121e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor  bool HasRelatedResultType = false;
31226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  TypeSourceInfo *ReturnTInfo = nullptr;
3123ccef371a67756233aa97770e4fccdfa868b3e2d0Steve Naroff  if (ReturnType) {
3124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    resultDeclType = GetTypeFromParser(ReturnType, &ReturnTInfo);
31251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3126ddb5a3926d715ab4354ca36117679e3f4d5d3e21Eli Friedman    if (CheckFunctionReturnType(resultDeclType, MethodLoc))
31276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return nullptr;
3128ddb5a3926d715ab4354ca36117679e3f4d5d3e21Eli Friedman
3129e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor    HasRelatedResultType = (resultDeclType == Context.getObjCInstanceType());
3130aab24a616de59c543d78d7636f22fb786053fefaFariborz Jahanian  } else { // get the type for "id".
31310ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner    resultDeclType = Context.getObjCIdType();
3132feb4fa165c5e8c40ffc8b1b655cc3c8071862b20Fariborz Jahanian    Diag(MethodLoc, diag::warn_missing_method_return_type)
313311d77169555480ee0a04c6e5bc390d8fde41175dArgyrios Kyrtzidis      << FixItHint::CreateInsertion(SelectorLocs.front(), "(id)");
3134aab24a616de59c543d78d7636f22fb786053fefaFariborz Jahanian  }
31351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ObjCMethodDecl *ObjCMethod = ObjCMethodDecl::Create(
3137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Context, MethodLoc, EndLoc, Sel, resultDeclType, ReturnTInfo, CurContext,
3138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      MethodType == tok::minus, isVariadic,
3139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      /*isPropertyAccessor=*/false,
3140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      /*isImplicitlyDeclared=*/false, /*isDefined=*/false,
3141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      MethodDeclKind == tok::objc_optional ? ObjCMethodDecl::Optional
3142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                           : ObjCMethodDecl::Required,
3143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      HasRelatedResultType);
31441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
31455f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<ParmVarDecl*, 16> Params;
31461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
31477db638d1222bfb2517ac54388e83169a4c76cf7eChris Lattner  for (unsigned i = 0, e = Sel.getNumArgs(); i != e; ++i) {
314858e4677a948e80c92deeebbcd3bdd9266adda798John McCall    QualType ArgType;
3149a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TypeSourceInfo *DI;
31501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
31517247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie    if (!ArgInfo[i].Type) {
315258e4677a948e80c92deeebbcd3bdd9266adda798John McCall      ArgType = Context.getObjCIdType();
31536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      DI = nullptr;
3154e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner    } else {
315558e4677a948e80c92deeebbcd3bdd9266adda798John McCall      ArgType = GetTypeFromParser(ArgInfo[i].Type, &DI);
3156e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner    }
31571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
31587f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian    LookupResult R(*this, ArgInfo[i].Name, ArgInfo[i].NameLoc,
31597f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian                   LookupOrdinaryName, ForRedeclaration);
31607f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian    LookupName(R, S);
31617f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian    if (R.isSingleResult()) {
31627f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian      NamedDecl *PrevDecl = R.getFoundDecl();
31637f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian      if (S->isDeclScope(PrevDecl)) {
316490ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian        Diag(ArgInfo[i].NameLoc,
316590ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian             (MethodDefinition ? diag::warn_method_param_redefinition
316690ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian                               : diag::warn_method_param_declaration))
31677f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian          << ArgInfo[i].Name;
31687f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian        Diag(PrevDecl->getLocation(),
31697f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian             diag::note_previous_declaration);
31707f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian      }
31717f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian    }
31727f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian
3173ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara    SourceLocation StartLoc = DI
3174ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara      ? DI->getTypeLoc().getBeginLoc()
3175ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara      : ArgInfo[i].NameLoc;
3176ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara
317781ef3e664d8ae250fbb68b2b6ccdeebb6c13ede5John McCall    ParmVarDecl* Param = CheckParameter(ObjCMethod, StartLoc,
317881ef3e664d8ae250fbb68b2b6ccdeebb6c13ede5John McCall                                        ArgInfo[i].NameLoc, ArgInfo[i].Name,
3179d2615cc53b916e8aae45783ca7113b93de515ce3Rafael Espindola                                        ArgType, DI, SC_None);
31801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
31817079886ab5a9df450ed773419f0ae81f8404e2aaJohn McCall    Param->setObjCMethodScopeInfo(i);
31827079886ab5a9df450ed773419f0ae81f8404e2aaJohn McCall
3183a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    Param->setObjCDeclQualifier(
3184e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner      CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier()));
31851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3186f97e8fa2966e3e49eac433336450f24ccbdf8b4aChris Lattner    // Apply the attributes to the parameter.
31879cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs);
31881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
318947b1d96bde79633d4aeded1cde2c5f870a58af24Fariborz Jahanian    if (Param->hasAttr<BlocksAttr>()) {
319047b1d96bde79633d4aeded1cde2c5f870a58af24Fariborz Jahanian      Diag(Param->getLocation(), diag::err_block_on_nonlocal);
319147b1d96bde79633d4aeded1cde2c5f870a58af24Fariborz Jahanian      Param->setInvalidDecl();
319247b1d96bde79633d4aeded1cde2c5f870a58af24Fariborz Jahanian    }
31937f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian    S->AddDecl(Param);
31947f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian    IdResolver.AddDecl(Param);
31957f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian
31964d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    Params.push_back(Param);
31974d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
31987f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian
31994f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian  for (unsigned i = 0, e = CNumArgs; i != e; ++i) {
3200d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    ParmVarDecl *Param = cast<ParmVarDecl>(CParamInfo[i].Param);
32014f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian    QualType ArgType = Param->getType();
32024f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian    if (ArgType.isNull())
32034f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian      ArgType = Context.getObjCIdType();
32044f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian    else
32054f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian      // Perform the default array/function conversions (C99 6.7.5.3p[7,8]).
320679e6bd379773447a74cc3e579d9081e4c5cb6d63Douglas Gregor      ArgType = Context.getAdjustedParameterType(ArgType);
3207ddb5a3926d715ab4354ca36117679e3f4d5d3e21Eli Friedman
32084f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian    Param->setDeclContext(ObjCMethod);
32094f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian    Params.push_back(Param);
32104f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian  }
32114f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian
3212491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  ObjCMethod->setMethodParams(Context, Params, SelectorLocs);
3213a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCMethod->setObjCDeclQualifier(
3214a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));
32153568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
32163568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  if (AttrList)
32179cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor    ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList);
32181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3219bdb2d5056fd675c27307b34efd371bbba6839e92Douglas Gregor  // Add the method now.
32206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  const ObjCMethodDecl *PrevMethod = nullptr;
32216c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall  if (ObjCImplDecl *ImpDecl = dyn_cast<ObjCImplDecl>(ClassDecl)) {
32224d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    if (MethodType == tok::minus) {
322317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      PrevMethod = ImpDecl->getInstanceMethod(Sel);
322417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      ImpDecl->addInstanceMethod(ObjCMethod);
32254d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    } else {
322617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      PrevMethod = ImpDecl->getClassMethod(Sel);
322717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      ImpDecl->addClassMethod(ObjCMethod);
32284d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    }
3229926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
32306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    ObjCMethodDecl *IMD = nullptr;
32317fda400103a5ae21fdc5f31b07c69cf60737cb29Fariborz Jahanian    if (ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface())
32327fda400103a5ae21fdc5f31b07c69cf60737cb29Fariborz Jahanian      IMD = IDecl->lookupMethod(ObjCMethod->getSelector(),
32337fda400103a5ae21fdc5f31b07c69cf60737cb29Fariborz Jahanian                                ObjCMethod->isInstanceMethod());
323438b3bd8bf3c424e82b4dca0acaec84af28666656Fariborz Jahanian    if (IMD && IMD->hasAttr<ObjCRequiresSuperAttr>() &&
323538b3bd8bf3c424e82b4dca0acaec84af28666656Fariborz Jahanian        !ObjCMethod->hasAttr<ObjCRequiresSuperAttr>()) {
323638b3bd8bf3c424e82b4dca0acaec84af28666656Fariborz Jahanian      // merge the attribute into implementation.
3237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ObjCMethod->addAttr(ObjCRequiresSuperAttr::CreateImplicit(Context,
3238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                   ObjCMethod->getLocation()));
3239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
3240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (isa<ObjCCategoryImplDecl>(ImpDecl)) {
3241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ObjCMethodFamily family =
3242651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        ObjCMethod->getSelector().getMethodFamily();
3243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (family == OMF_dealloc && IMD && IMD->isOverriding())
3244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        Diag(ObjCMethod->getLocation(), diag::warn_dealloc_in_category)
32453306ec1923973d7b5767b23ba95915af2fec87d7Ted Kremenek          << ObjCMethod->getDeclName();
3246ec236787c5868eef53a807ca1a68b6b0b8c604c6Fariborz Jahanian    }
3247bdb2d5056fd675c27307b34efd371bbba6839e92Douglas Gregor  } else {
3248bdb2d5056fd675c27307b34efd371bbba6839e92Douglas Gregor    cast<DeclContext>(ClassDecl)->addDecl(ObjCMethod);
32494d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  }
32506c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
32514d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner  if (PrevMethod) {
32524d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner    // You can never have two method definitions with the same name.
32535f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner    Diag(ObjCMethod->getLocation(), diag::err_duplicate_method_decl)
3254077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner      << ObjCMethod->getDeclName();
32555f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner    Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
3256fbff0c4510c7f0e0f30a005960e434b973f5bd21Fariborz Jahanian    ObjCMethod->setInvalidDecl();
3257fbff0c4510c7f0e0f30a005960e434b973f5bd21Fariborz Jahanian    return ObjCMethod;
32581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
325954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
3260926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  // If this Objective-C method does not have a related result type, but we
3261926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  // are allowed to infer related result types, try to do so based on the
3262926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  // method family.
3263926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  ObjCInterfaceDecl *CurrentClass = dyn_cast<ObjCInterfaceDecl>(ClassDecl);
3264926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  if (!CurrentClass) {
3265926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(ClassDecl))
3266926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      CurrentClass = Cat->getClassInterface();
3267926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    else if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(ClassDecl))
3268926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      CurrentClass = Impl->getClassInterface();
3269926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    else if (ObjCCategoryImplDecl *CatImpl
3270926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                   = dyn_cast<ObjCCategoryImplDecl>(ClassDecl))
3271926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      CurrentClass = CatImpl->getClassInterface();
3272926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  }
32736c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
3274e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor  ResultTypeCompatibilityKind RTC
3275e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor    = CheckRelatedResultTypeCompatibility(*this, ObjCMethod, CurrentClass);
32766c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
3277e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  CheckObjCMethodOverrides(ObjCMethod, CurrentClass, RTC);
32786c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall
3279f85e193739c953358c865005855253af4f68a497John McCall  bool ARCError = false;
32804e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().ObjCAutoRefCount)
3281b846381fc3099b2340ba8c74d16178203a60d9a0John McCall    ARCError = CheckARCMethodDecl(ObjCMethod);
3282f85e193739c953358c865005855253af4f68a497John McCall
3283e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor  // Infer the related result type when possible.
3284e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis  if (!ARCError && RTC == Sema::RTC_Compatible &&
3285e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor      !ObjCMethod->hasRelatedResultType() &&
3286e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor      LangOpts.ObjCInferRelatedResultType) {
3287926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    bool InferRelatedResultType = false;
3288926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    switch (ObjCMethod->getMethodFamily()) {
3289926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    case OMF_None:
3290926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    case OMF_copy:
3291926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    case OMF_dealloc:
329280cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber    case OMF_finalize:
3293926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    case OMF_mutableCopy:
3294926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    case OMF_release:
3295926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    case OMF_retainCount:
3296176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    case OMF_initialize:
32979670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian    case OMF_performSelector:
3298926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      break;
3299926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
3300926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    case OMF_alloc:
3301926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    case OMF_new:
330233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar        InferRelatedResultType = ObjCMethod->isClassMethod();
3303926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      break;
3304926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
3305926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    case OMF_init:
3306926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    case OMF_autorelease:
3307926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    case OMF_retain:
3308926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    case OMF_self:
3309926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      InferRelatedResultType = ObjCMethod->isInstanceMethod();
3310926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      break;
3311926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    }
3312926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
331333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar    if (InferRelatedResultType &&
331433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar        !ObjCMethod->getReturnType()->isObjCIndependentClassType())
3315926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      ObjCMethod->SetRelatedResultType();
3316926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  }
3317a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko
3318a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko  ActOnDocumentableDecl(ObjCMethod);
3319a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko
3320d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  return ObjCMethod;
33214d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner}
33224d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner
3323cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattnerbool Sema::CheckObjCDeclScope(Decl *D) {
332458a764940df0cd41767367eb2f4fced6f374176bFariborz Jahanian  // Following is also an error. But it is caused by a missing @end
332558a764940df0cd41767367eb2f4fced6f374176bFariborz Jahanian  // and diagnostic is issued elsewhere.
3326fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis  if (isa<ObjCContainerDecl>(CurContext->getRedeclContext()))
3327fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis    return false;
3328fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis
3329fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis  // If we switched context to translation unit while we are still lexically in
3330fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis  // an objc container, it means the parser missed emitting an error.
3331fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis  if (isa<TranslationUnitDecl>(getCurLexicalContext()->getRedeclContext()))
3332a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian    return false;
3333a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian
333415281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson  Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
333515281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson  D->setInvalidDecl();
33361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
333715281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson  return true;
333815281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson}
3339cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner
33401dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// Called whenever \@defs(ClassName) is encountered in the source.  Inserts the
3341cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner/// instance variables of ClassName into Decls.
3342d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Sema::ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart,
3343cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner                     IdentifierInfo *ClassName,
33445f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                     SmallVectorImpl<Decl*> &Decls) {
3345cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner  // Check that ClassName is a valid class
3346c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  ObjCInterfaceDecl *Class = getObjCInterfaceDecl(ClassName, DeclStart);
3347cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner  if (!Class) {
3348cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner    Diag(DeclStart, diag::err_undef_interface) << ClassName;
3349cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner    return;
3350cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner  }
3351260611a32535c851237926bfcf78869b13c07d5bJohn McCall  if (LangOpts.ObjCRuntime.isNonFragile()) {
33520468fb99068c40990a3b1451938fee5b90daf941Fariborz Jahanian    Diag(DeclStart, diag::err_atdef_nonfragile_interface);
33530468fb99068c40990a3b1451938fee5b90daf941Fariborz Jahanian    return;
33540468fb99068c40990a3b1451938fee5b90daf941Fariborz Jahanian  }
33551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3356cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner  // Collect the instance variables
3357db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  SmallVector<const ObjCIvarDecl*, 32> Ivars;
33582c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian  Context.DeepCollectObjCIvars(Class, true, Ivars);
33594183335fa8bfce8dd2d910dc992dace8c5f66b0dFariborz Jahanian  // For each ivar, create a fresh ObjCAtDefsFieldDecl.
33602c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian  for (unsigned i = 0; i < Ivars.size(); i++) {
3361db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose    const FieldDecl* ID = cast<FieldDecl>(Ivars[i]);
3362d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    RecordDecl *Record = dyn_cast<RecordDecl>(TagD);
3363ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara    Decl *FD = ObjCAtDefsFieldDecl::Create(Context, Record,
3364ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                           /*FIXME: StartL=*/ID->getLocation(),
3365ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                           ID->getLocation(),
33664183335fa8bfce8dd2d910dc992dace8c5f66b0dFariborz Jahanian                                           ID->getIdentifier(), ID->getType(),
33674183335fa8bfce8dd2d910dc992dace8c5f66b0dFariborz Jahanian                                           ID->getBitWidth());
3368d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    Decls.push_back(FD);
33694183335fa8bfce8dd2d910dc992dace8c5f66b0dFariborz Jahanian  }
33701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3371cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner  // Introduce all of these fields into the appropriate scope.
33725f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  for (SmallVectorImpl<Decl*>::iterator D = Decls.begin();
3373cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner       D != Decls.end(); ++D) {
3374d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    FieldDecl *FD = cast<FieldDecl>(*D);
33754e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (getLangOpts().CPlusPlus)
3376cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner      PushOnScopeChains(cast<FieldDecl>(FD), S);
3377d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD))
337817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      Record->addDecl(FD);
3379cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner  }
3380cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner}
3381cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner
3382160b5630aa781ac348303e1ae088d27016637778Douglas Gregor/// \brief Build a type-check a new Objective-C exception variable declaration.
3383ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo BagnaraVarDecl *Sema::BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType T,
3384ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                      SourceLocation StartLoc,
3385ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                      SourceLocation IdLoc,
3386ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                      IdentifierInfo *Id,
3387160b5630aa781ac348303e1ae088d27016637778Douglas Gregor                                      bool Invalid) {
3388160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  // ISO/IEC TR 18037 S6.7.3: "The type of an object with automatic storage
3389160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  // duration shall not be qualified by an address-space qualifier."
3390160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  // Since all parameters have automatic store duration, they can not have
3391160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  // an address space.
3392160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  if (T.getAddressSpace() != 0) {
3393ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara    Diag(IdLoc, diag::err_arg_with_address_space);
3394160b5630aa781ac348303e1ae088d27016637778Douglas Gregor    Invalid = true;
3395160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  }
3396160b5630aa781ac348303e1ae088d27016637778Douglas Gregor
3397160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  // An @catch parameter must be an unqualified object pointer type;
3398160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  // FIXME: Recover from "NSObject foo" by inserting the * in "NSObject *foo"?
3399160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  if (Invalid) {
3400160b5630aa781ac348303e1ae088d27016637778Douglas Gregor    // Don't do any further checking.
3401be270a0fae647ae3fb4d6a21ba1ea5ab9c40853aDouglas Gregor  } else if (T->isDependentType()) {
3402be270a0fae647ae3fb4d6a21ba1ea5ab9c40853aDouglas Gregor    // Okay: we don't know what this type will instantiate to.
3403160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  } else if (!T->isObjCObjectPointerType()) {
3404160b5630aa781ac348303e1ae088d27016637778Douglas Gregor    Invalid = true;
3405ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara    Diag(IdLoc ,diag::err_catch_param_not_objc_type);
3406160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  } else if (T->isObjCQualifiedIdType()) {
3407160b5630aa781ac348303e1ae088d27016637778Douglas Gregor    Invalid = true;
3408ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara    Diag(IdLoc, diag::err_illegal_qualifiers_on_catch_parm);
3409160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  }
3410160b5630aa781ac348303e1ae088d27016637778Douglas Gregor
3411ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  VarDecl *New = VarDecl::Create(Context, CurContext, StartLoc, IdLoc, Id,
3412d2615cc53b916e8aae45783ca7113b93de515ce3Rafael Espindola                                 T, TInfo, SC_None);
3413324b54d3f60d92a82815512119791ce1c285b63eDouglas Gregor  New->setExceptionVariable(true);
3414324b54d3f60d92a82815512119791ce1c285b63eDouglas Gregor
34159aab9c4116bb3ea876d92d4af10bff7f4c451f24Douglas Gregor  // In ARC, infer 'retaining' for variables of retainable type.
34164e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(New))
34179aab9c4116bb3ea876d92d4af10bff7f4c451f24Douglas Gregor    Invalid = true;
34189aab9c4116bb3ea876d92d4af10bff7f4c451f24Douglas Gregor
3419160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  if (Invalid)
3420160b5630aa781ac348303e1ae088d27016637778Douglas Gregor    New->setInvalidDecl();
3421160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  return New;
3422160b5630aa781ac348303e1ae088d27016637778Douglas Gregor}
3423160b5630aa781ac348303e1ae088d27016637778Douglas Gregor
3424d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
3425160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  const DeclSpec &DS = D.getDeclSpec();
3426160b5630aa781ac348303e1ae088d27016637778Douglas Gregor
3427160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  // We allow the "register" storage class on exception variables because
3428160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  // GCC did, but we drop it completely. Any other storage class is an error.
3429160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  if (DS.getStorageClassSpec() == DeclSpec::SCS_register) {
3430160b5630aa781ac348303e1ae088d27016637778Douglas Gregor    Diag(DS.getStorageClassSpecLoc(), diag::warn_register_objc_catch_parm)
3431160b5630aa781ac348303e1ae088d27016637778Douglas Gregor      << FixItHint::CreateRemoval(SourceRange(DS.getStorageClassSpecLoc()));
3432ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith  } else if (DeclSpec::SCS SCS = DS.getStorageClassSpec()) {
3433160b5630aa781ac348303e1ae088d27016637778Douglas Gregor    Diag(DS.getStorageClassSpecLoc(), diag::err_storage_spec_on_catch_parm)
3434ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith      << DeclSpec::getSpecifierName(SCS);
3435ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith  }
3436ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith  if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec())
3437ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith    Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
3438ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith         diag::err_invalid_thread)
3439ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith     << DeclSpec::getSpecifierName(TSCS);
3440160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  D.getMutableDeclSpec().ClearStorageClassSpecs();
3441160b5630aa781ac348303e1ae088d27016637778Douglas Gregor
3442c7f811638f8603fa373d2be724e8b1c8ba51ad75Richard Smith  DiagnoseFunctionSpecifiers(D.getDeclSpec());
3443160b5630aa781ac348303e1ae088d27016637778Douglas Gregor
3444160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  // Check that there are no default arguments inside the type of this
3445160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  // exception object (C++ only).
34464e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().CPlusPlus)
3447160b5630aa781ac348303e1ae088d27016637778Douglas Gregor    CheckExtraCXXDefaultArguments(D);
3448160b5630aa781ac348303e1ae088d27016637778Douglas Gregor
34493215398dc9dac2be19a9fc1df929e6b7d83eafcaArgyrios Kyrtzidis  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
3450bf1a028246d884a540aeafa38e89be59a269b072John McCall  QualType ExceptionType = TInfo->getType();
3451160b5630aa781ac348303e1ae088d27016637778Douglas Gregor
3452ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  VarDecl *New = BuildObjCExceptionDecl(TInfo, ExceptionType,
3453ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                        D.getSourceRange().getBegin(),
3454ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                        D.getIdentifierLoc(),
3455ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                                        D.getIdentifier(),
3456160b5630aa781ac348303e1ae088d27016637778Douglas Gregor                                        D.isInvalidType());
3457160b5630aa781ac348303e1ae088d27016637778Douglas Gregor
3458160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  // Parameter declarators cannot be qualified (C++ [dcl.meaning]p1).
3459160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  if (D.getCXXScopeSpec().isSet()) {
3460160b5630aa781ac348303e1ae088d27016637778Douglas Gregor    Diag(D.getIdentifierLoc(), diag::err_qualified_objc_catch_parm)
3461160b5630aa781ac348303e1ae088d27016637778Douglas Gregor      << D.getCXXScopeSpec().getRange();
3462160b5630aa781ac348303e1ae088d27016637778Douglas Gregor    New->setInvalidDecl();
3463160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  }
3464160b5630aa781ac348303e1ae088d27016637778Douglas Gregor
3465160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  // Add the parameter declaration into this scope.
3466d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  S->AddDecl(New);
3467160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  if (D.getIdentifier())
3468160b5630aa781ac348303e1ae088d27016637778Douglas Gregor    IdResolver.AddDecl(New);
3469160b5630aa781ac348303e1ae088d27016637778Douglas Gregor
3470160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  ProcessDeclAttributes(S, New, D);
3471160b5630aa781ac348303e1ae088d27016637778Douglas Gregor
3472160b5630aa781ac348303e1ae088d27016637778Douglas Gregor  if (New->hasAttr<BlocksAttr>())
3473160b5630aa781ac348303e1ae088d27016637778Douglas Gregor    Diag(New->getLocation(), diag::err_block_on_nonlocal);
3474d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  return New;
34754e6c0d19b7c072758922cf80525a81aeefc6e64bDouglas Gregor}
3476786cd154f2a48d2b464679d33fcd5df0cd794c06Fariborz Jahanian
3477786cd154f2a48d2b464679d33fcd5df0cd794c06Fariborz Jahanian/// CollectIvarsToConstructOrDestruct - Collect those ivars which require
3478e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian/// initialization.
34792c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanianvoid Sema::CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI,
34805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
34812c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian  for (ObjCIvarDecl *Iv = OI->all_declared_ivar_begin(); Iv;
34822c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian       Iv= Iv->getNextIvar()) {
3483786cd154f2a48d2b464679d33fcd5df0cd794c06Fariborz Jahanian    QualType QT = Context.getBaseElementType(Iv->getType());
348468dd3ee3b5ae5b7694b4a21e34b4355431ed0457Douglas Gregor    if (QT->isRecordType())
34852c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian      Ivars.push_back(Iv);
3486786cd154f2a48d2b464679d33fcd5df0cd794c06Fariborz Jahanian  }
3487786cd154f2a48d2b464679d33fcd5df0cd794c06Fariborz Jahanian}
3488e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian
34893fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanianvoid Sema::DiagnoseUseOfUnimplementedSelectors() {
34905b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor  // Load referenced selectors from the external source.
34915b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor  if (ExternalSource) {
34925b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor    SmallVector<std::pair<Selector, SourceLocation>, 4> Sels;
34935b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor    ExternalSource->ReadReferencedSelectors(Sels);
34945b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor    for (unsigned I = 0, N = Sels.size(); I != N; ++I)
34955b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor      ReferencedSelectors[Sels[I].first] = Sels[I].second;
34965b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor  }
34975b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor
34988b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian  // Warning will be issued only when selector table is
34998b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian  // generated (which means there is at lease one implementation
35008b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian  // in the TU). This is to match gcc's behavior.
35018b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian  if (ReferencedSelectors.empty() ||
35028b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian      !Context.AnyObjCImplementation())
35033fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian    return;
35043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  for (auto &SelectorAndLocation : ReferencedSelectors) {
35053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    Selector Sel = SelectorAndLocation.first;
35063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    SourceLocation Loc = SelectorAndLocation.second;
35073fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian    if (!LookupImplementedMethodInGlobalPool(Sel))
35083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      Diag(Loc, diag::warn_unimplemented_selector) << Sel;
35093fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian  }
35103fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian  return;
35113fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian}
35124e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian
35134e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz JahanianObjCIvarDecl *
35144e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz JahanianSema::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method,
35154e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian                                     const ObjCPropertyDecl *&PDecl) const {
3516651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (Method->isClassMethod())
35176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
35184e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian  const ObjCInterfaceDecl *IDecl = Method->getClassInterface();
35194e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian  if (!IDecl)
35206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
3521651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Method = IDecl->lookupMethod(Method->getSelector(), /*isInstance=*/true,
3522651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                               /*shallowCategoryLookup=*/false,
3523651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                               /*followSuper=*/false);
35244e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian  if (!Method || !Method->isPropertyAccessor())
35256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
3526651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if ((PDecl = Method->findPropertyDecl()))
3527651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl()) {
3528651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // property backing ivar must belong to property's class
3529651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // or be a private ivar in class's implementation.
3530651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      // FIXME. fix the const-ness issue.
3531651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      IV = const_cast<ObjCInterfaceDecl *>(IDecl)->lookupInstanceVariable(
3532651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                        IV->getIdentifier());
3533651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return IV;
3534651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
35356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
35364e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian}
35374e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian
3538651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace {
3539651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Used by Sema::DiagnoseUnusedBackingIvarInAccessor to check if a property
3540651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// accessor references the backing ivar.
3541651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  class UnusedBackingIvarChecker :
3542651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      public DataRecursiveASTVisitor<UnusedBackingIvarChecker> {
3543651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  public:
3544651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Sema &S;
3545651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    const ObjCMethodDecl *Method;
3546651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    const ObjCIvarDecl *IvarD;
3547651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    bool AccessedIvar;
3548651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    bool InvokedSelfMethod;
3549651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3550651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    UnusedBackingIvarChecker(Sema &S, const ObjCMethodDecl *Method,
3551651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             const ObjCIvarDecl *IvarD)
3552651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      : S(S), Method(Method), IvarD(IvarD),
3553651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        AccessedIvar(false), InvokedSelfMethod(false) {
3554651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      assert(IvarD);
3555651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
3556651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3557651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
3558651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (E->getDecl() == IvarD) {
3559651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        AccessedIvar = true;
3560651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        return false;
3561651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      }
3562651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return true;
3563651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
3564651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
3566651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (E->getReceiverKind() == ObjCMessageExpr::Instance &&
3567651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          S.isSelfExpr(E->getInstanceReceiver(), Method)) {
3568651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        InvokedSelfMethod = true;
3569651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      }
3570651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return true;
3571651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
3572651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
3573651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
3574651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3575651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Sema::DiagnoseUnusedBackingIvarInAccessor(Scope *S,
3576651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                          const ObjCImplementationDecl *ImplD) {
3577651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (S->hasUnrecoverableErrorOccurred())
35784e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian    return;
3579651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3580651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *CurMethod : ImplD->instance_methods()) {
3581651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    unsigned DIAG = diag::warn_unused_property_backing_ivar;
3582651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    SourceLocation Loc = CurMethod->getLocation();
3583c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    if (Diags.isIgnored(DIAG, Loc))
3584651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      continue;
3585651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3586651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    const ObjCPropertyDecl *PDecl;
3587651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    const ObjCIvarDecl *IV = GetIvarBackingPropertyAccessor(CurMethod, PDecl);
3588651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (!IV)
3589651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      continue;
3590651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3591651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    UnusedBackingIvarChecker Checker(*this, CurMethod, IV);
3592651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Checker.TraverseStmt(CurMethod->getBody());
3593651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (Checker.AccessedIvar)
3594651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      continue;
3595651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3596651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // Do not issue this warning if backing ivar is used somewhere and accessor
3597651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // implementation makes a self call. This is to prevent false positive in
3598651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // cases where the ivar is accessed by another method that the accessor
3599651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // delegates to.
3600651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (!IV->isReferenced() || !Checker.InvokedSelfMethod) {
3601651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Diag(Loc, DIAG) << IV;
3602651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Diag(PDecl->getLocation(), diag::note_property_declare);
3603651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
36044e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian  }
36054e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian}
3606