xref: /aosp_15_r20/external/clang/lib/Sema/SemaDeclObjC.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===--- SemaDeclObjC.cpp - Semantic Analysis for ObjC Declarations -------===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li //  This file implements semantic analysis for Objective C declarations.
11*67e74705SXin Li //
12*67e74705SXin Li //===----------------------------------------------------------------------===//
13*67e74705SXin Li 
14*67e74705SXin Li #include "clang/Sema/SemaInternal.h"
15*67e74705SXin Li #include "clang/AST/ASTConsumer.h"
16*67e74705SXin Li #include "clang/AST/ASTContext.h"
17*67e74705SXin Li #include "clang/AST/ASTMutationListener.h"
18*67e74705SXin Li #include "clang/AST/RecursiveASTVisitor.h"
19*67e74705SXin Li #include "clang/AST/DeclObjC.h"
20*67e74705SXin Li #include "clang/AST/Expr.h"
21*67e74705SXin Li #include "clang/AST/ExprObjC.h"
22*67e74705SXin Li #include "clang/Basic/SourceManager.h"
23*67e74705SXin Li #include "clang/Sema/DeclSpec.h"
24*67e74705SXin Li #include "clang/Sema/Lookup.h"
25*67e74705SXin Li #include "clang/Sema/Scope.h"
26*67e74705SXin Li #include "clang/Sema/ScopeInfo.h"
27*67e74705SXin Li #include "llvm/ADT/DenseMap.h"
28*67e74705SXin Li #include "llvm/ADT/DenseSet.h"
29*67e74705SXin Li #include "TypeLocBuilder.h"
30*67e74705SXin Li 
31*67e74705SXin Li using namespace clang;
32*67e74705SXin Li 
33*67e74705SXin Li /// Check whether the given method, which must be in the 'init'
34*67e74705SXin Li /// family, is a valid member of that family.
35*67e74705SXin Li ///
36*67e74705SXin Li /// \param receiverTypeIfCall - if null, check this as if declaring it;
37*67e74705SXin Li ///   if non-null, check this as if making a call to it with the given
38*67e74705SXin Li ///   receiver type
39*67e74705SXin Li ///
40*67e74705SXin Li /// \return true to indicate that there was an error and appropriate
41*67e74705SXin Li ///   actions were taken
checkInitMethod(ObjCMethodDecl * method,QualType receiverTypeIfCall)42*67e74705SXin Li bool Sema::checkInitMethod(ObjCMethodDecl *method,
43*67e74705SXin Li                            QualType receiverTypeIfCall) {
44*67e74705SXin Li   if (method->isInvalidDecl()) return true;
45*67e74705SXin Li 
46*67e74705SXin Li   // This castAs is safe: methods that don't return an object
47*67e74705SXin Li   // pointer won't be inferred as inits and will reject an explicit
48*67e74705SXin Li   // objc_method_family(init).
49*67e74705SXin Li 
50*67e74705SXin Li   // We ignore protocols here.  Should we?  What about Class?
51*67e74705SXin Li 
52*67e74705SXin Li   const ObjCObjectType *result =
53*67e74705SXin Li       method->getReturnType()->castAs<ObjCObjectPointerType>()->getObjectType();
54*67e74705SXin Li 
55*67e74705SXin Li   if (result->isObjCId()) {
56*67e74705SXin Li     return false;
57*67e74705SXin Li   } else if (result->isObjCClass()) {
58*67e74705SXin Li     // fall through: always an error
59*67e74705SXin Li   } else {
60*67e74705SXin Li     ObjCInterfaceDecl *resultClass = result->getInterface();
61*67e74705SXin Li     assert(resultClass && "unexpected object type!");
62*67e74705SXin Li 
63*67e74705SXin Li     // It's okay for the result type to still be a forward declaration
64*67e74705SXin Li     // if we're checking an interface declaration.
65*67e74705SXin Li     if (!resultClass->hasDefinition()) {
66*67e74705SXin Li       if (receiverTypeIfCall.isNull() &&
67*67e74705SXin Li           !isa<ObjCImplementationDecl>(method->getDeclContext()))
68*67e74705SXin Li         return false;
69*67e74705SXin Li 
70*67e74705SXin Li     // Otherwise, we try to compare class types.
71*67e74705SXin Li     } else {
72*67e74705SXin Li       // If this method was declared in a protocol, we can't check
73*67e74705SXin Li       // anything unless we have a receiver type that's an interface.
74*67e74705SXin Li       const ObjCInterfaceDecl *receiverClass = nullptr;
75*67e74705SXin Li       if (isa<ObjCProtocolDecl>(method->getDeclContext())) {
76*67e74705SXin Li         if (receiverTypeIfCall.isNull())
77*67e74705SXin Li           return false;
78*67e74705SXin Li 
79*67e74705SXin Li         receiverClass = receiverTypeIfCall->castAs<ObjCObjectPointerType>()
80*67e74705SXin Li           ->getInterfaceDecl();
81*67e74705SXin Li 
82*67e74705SXin Li         // This can be null for calls to e.g. id<Foo>.
83*67e74705SXin Li         if (!receiverClass) return false;
84*67e74705SXin Li       } else {
85*67e74705SXin Li         receiverClass = method->getClassInterface();
86*67e74705SXin Li         assert(receiverClass && "method not associated with a class!");
87*67e74705SXin Li       }
88*67e74705SXin Li 
89*67e74705SXin Li       // If either class is a subclass of the other, it's fine.
90*67e74705SXin Li       if (receiverClass->isSuperClassOf(resultClass) ||
91*67e74705SXin Li           resultClass->isSuperClassOf(receiverClass))
92*67e74705SXin Li         return false;
93*67e74705SXin Li     }
94*67e74705SXin Li   }
95*67e74705SXin Li 
96*67e74705SXin Li   SourceLocation loc = method->getLocation();
97*67e74705SXin Li 
98*67e74705SXin Li   // If we're in a system header, and this is not a call, just make
99*67e74705SXin Li   // the method unusable.
100*67e74705SXin Li   if (receiverTypeIfCall.isNull() && getSourceManager().isInSystemHeader(loc)) {
101*67e74705SXin Li     method->addAttr(UnavailableAttr::CreateImplicit(Context, "",
102*67e74705SXin Li                       UnavailableAttr::IR_ARCInitReturnsUnrelated, loc));
103*67e74705SXin Li     return true;
104*67e74705SXin Li   }
105*67e74705SXin Li 
106*67e74705SXin Li   // Otherwise, it's an error.
107*67e74705SXin Li   Diag(loc, diag::err_arc_init_method_unrelated_result_type);
108*67e74705SXin Li   method->setInvalidDecl();
109*67e74705SXin Li   return true;
110*67e74705SXin Li }
111*67e74705SXin Li 
CheckObjCMethodOverride(ObjCMethodDecl * NewMethod,const ObjCMethodDecl * Overridden)112*67e74705SXin Li void Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod,
113*67e74705SXin Li                                    const ObjCMethodDecl *Overridden) {
114*67e74705SXin Li   if (Overridden->hasRelatedResultType() &&
115*67e74705SXin Li       !NewMethod->hasRelatedResultType()) {
116*67e74705SXin Li     // This can only happen when the method follows a naming convention that
117*67e74705SXin Li     // implies a related result type, and the original (overridden) method has
118*67e74705SXin Li     // a suitable return type, but the new (overriding) method does not have
119*67e74705SXin Li     // a suitable return type.
120*67e74705SXin Li     QualType ResultType = NewMethod->getReturnType();
121*67e74705SXin Li     SourceRange ResultTypeRange = NewMethod->getReturnTypeSourceRange();
122*67e74705SXin Li 
123*67e74705SXin Li     // Figure out which class this method is part of, if any.
124*67e74705SXin Li     ObjCInterfaceDecl *CurrentClass
125*67e74705SXin Li       = dyn_cast<ObjCInterfaceDecl>(NewMethod->getDeclContext());
126*67e74705SXin Li     if (!CurrentClass) {
127*67e74705SXin Li       DeclContext *DC = NewMethod->getDeclContext();
128*67e74705SXin Li       if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(DC))
129*67e74705SXin Li         CurrentClass = Cat->getClassInterface();
130*67e74705SXin Li       else if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(DC))
131*67e74705SXin Li         CurrentClass = Impl->getClassInterface();
132*67e74705SXin Li       else if (ObjCCategoryImplDecl *CatImpl
133*67e74705SXin Li                = dyn_cast<ObjCCategoryImplDecl>(DC))
134*67e74705SXin Li         CurrentClass = CatImpl->getClassInterface();
135*67e74705SXin Li     }
136*67e74705SXin Li 
137*67e74705SXin Li     if (CurrentClass) {
138*67e74705SXin Li       Diag(NewMethod->getLocation(),
139*67e74705SXin Li            diag::warn_related_result_type_compatibility_class)
140*67e74705SXin Li         << Context.getObjCInterfaceType(CurrentClass)
141*67e74705SXin Li         << ResultType
142*67e74705SXin Li         << ResultTypeRange;
143*67e74705SXin Li     } else {
144*67e74705SXin Li       Diag(NewMethod->getLocation(),
145*67e74705SXin Li            diag::warn_related_result_type_compatibility_protocol)
146*67e74705SXin Li         << ResultType
147*67e74705SXin Li         << ResultTypeRange;
148*67e74705SXin Li     }
149*67e74705SXin Li 
150*67e74705SXin Li     if (ObjCMethodFamily Family = Overridden->getMethodFamily())
151*67e74705SXin Li       Diag(Overridden->getLocation(),
152*67e74705SXin Li            diag::note_related_result_type_family)
153*67e74705SXin Li         << /*overridden method*/ 0
154*67e74705SXin Li         << Family;
155*67e74705SXin Li     else
156*67e74705SXin Li       Diag(Overridden->getLocation(),
157*67e74705SXin Li            diag::note_related_result_type_overridden);
158*67e74705SXin Li   }
159*67e74705SXin Li   if (getLangOpts().ObjCAutoRefCount) {
160*67e74705SXin Li     if ((NewMethod->hasAttr<NSReturnsRetainedAttr>() !=
161*67e74705SXin Li          Overridden->hasAttr<NSReturnsRetainedAttr>())) {
162*67e74705SXin Li         Diag(NewMethod->getLocation(),
163*67e74705SXin Li              diag::err_nsreturns_retained_attribute_mismatch) << 1;
164*67e74705SXin Li         Diag(Overridden->getLocation(), diag::note_previous_decl)
165*67e74705SXin Li         << "method";
166*67e74705SXin Li     }
167*67e74705SXin Li     if ((NewMethod->hasAttr<NSReturnsNotRetainedAttr>() !=
168*67e74705SXin Li               Overridden->hasAttr<NSReturnsNotRetainedAttr>())) {
169*67e74705SXin Li         Diag(NewMethod->getLocation(),
170*67e74705SXin Li              diag::err_nsreturns_retained_attribute_mismatch) << 0;
171*67e74705SXin Li         Diag(Overridden->getLocation(), diag::note_previous_decl)
172*67e74705SXin Li         << "method";
173*67e74705SXin Li     }
174*67e74705SXin Li     ObjCMethodDecl::param_const_iterator oi = Overridden->param_begin(),
175*67e74705SXin Li                                          oe = Overridden->param_end();
176*67e74705SXin Li     for (ObjCMethodDecl::param_iterator
177*67e74705SXin Li            ni = NewMethod->param_begin(), ne = NewMethod->param_end();
178*67e74705SXin Li          ni != ne && oi != oe; ++ni, ++oi) {
179*67e74705SXin Li       const ParmVarDecl *oldDecl = (*oi);
180*67e74705SXin Li       ParmVarDecl *newDecl = (*ni);
181*67e74705SXin Li       if (newDecl->hasAttr<NSConsumedAttr>() !=
182*67e74705SXin Li           oldDecl->hasAttr<NSConsumedAttr>()) {
183*67e74705SXin Li         Diag(newDecl->getLocation(),
184*67e74705SXin Li              diag::err_nsconsumed_attribute_mismatch);
185*67e74705SXin Li         Diag(oldDecl->getLocation(), diag::note_previous_decl)
186*67e74705SXin Li           << "parameter";
187*67e74705SXin Li       }
188*67e74705SXin Li     }
189*67e74705SXin Li   }
190*67e74705SXin Li }
191*67e74705SXin Li 
192*67e74705SXin Li /// \brief Check a method declaration for compatibility with the Objective-C
193*67e74705SXin Li /// ARC conventions.
CheckARCMethodDecl(ObjCMethodDecl * method)194*67e74705SXin Li bool Sema::CheckARCMethodDecl(ObjCMethodDecl *method) {
195*67e74705SXin Li   ObjCMethodFamily family = method->getMethodFamily();
196*67e74705SXin Li   switch (family) {
197*67e74705SXin Li   case OMF_None:
198*67e74705SXin Li   case OMF_finalize:
199*67e74705SXin Li   case OMF_retain:
200*67e74705SXin Li   case OMF_release:
201*67e74705SXin Li   case OMF_autorelease:
202*67e74705SXin Li   case OMF_retainCount:
203*67e74705SXin Li   case OMF_self:
204*67e74705SXin Li   case OMF_initialize:
205*67e74705SXin Li   case OMF_performSelector:
206*67e74705SXin Li     return false;
207*67e74705SXin Li 
208*67e74705SXin Li   case OMF_dealloc:
209*67e74705SXin Li     if (!Context.hasSameType(method->getReturnType(), Context.VoidTy)) {
210*67e74705SXin Li       SourceRange ResultTypeRange = method->getReturnTypeSourceRange();
211*67e74705SXin Li       if (ResultTypeRange.isInvalid())
212*67e74705SXin Li         Diag(method->getLocation(), diag::error_dealloc_bad_result_type)
213*67e74705SXin Li             << method->getReturnType()
214*67e74705SXin Li             << FixItHint::CreateInsertion(method->getSelectorLoc(0), "(void)");
215*67e74705SXin Li       else
216*67e74705SXin Li         Diag(method->getLocation(), diag::error_dealloc_bad_result_type)
217*67e74705SXin Li             << method->getReturnType()
218*67e74705SXin Li             << FixItHint::CreateReplacement(ResultTypeRange, "void");
219*67e74705SXin Li       return true;
220*67e74705SXin Li     }
221*67e74705SXin Li     return false;
222*67e74705SXin Li 
223*67e74705SXin Li   case OMF_init:
224*67e74705SXin Li     // If the method doesn't obey the init rules, don't bother annotating it.
225*67e74705SXin Li     if (checkInitMethod(method, QualType()))
226*67e74705SXin Li       return true;
227*67e74705SXin Li 
228*67e74705SXin Li     method->addAttr(NSConsumesSelfAttr::CreateImplicit(Context));
229*67e74705SXin Li 
230*67e74705SXin Li     // Don't add a second copy of this attribute, but otherwise don't
231*67e74705SXin Li     // let it be suppressed.
232*67e74705SXin Li     if (method->hasAttr<NSReturnsRetainedAttr>())
233*67e74705SXin Li       return false;
234*67e74705SXin Li     break;
235*67e74705SXin Li 
236*67e74705SXin Li   case OMF_alloc:
237*67e74705SXin Li   case OMF_copy:
238*67e74705SXin Li   case OMF_mutableCopy:
239*67e74705SXin Li   case OMF_new:
240*67e74705SXin Li     if (method->hasAttr<NSReturnsRetainedAttr>() ||
241*67e74705SXin Li         method->hasAttr<NSReturnsNotRetainedAttr>() ||
242*67e74705SXin Li         method->hasAttr<NSReturnsAutoreleasedAttr>())
243*67e74705SXin Li       return false;
244*67e74705SXin Li     break;
245*67e74705SXin Li   }
246*67e74705SXin Li 
247*67e74705SXin Li   method->addAttr(NSReturnsRetainedAttr::CreateImplicit(Context));
248*67e74705SXin Li   return false;
249*67e74705SXin Li }
250*67e74705SXin Li 
DiagnoseObjCImplementedDeprecations(Sema & S,NamedDecl * ND,SourceLocation ImplLoc,int select)251*67e74705SXin Li static void DiagnoseObjCImplementedDeprecations(Sema &S,
252*67e74705SXin Li                                                 NamedDecl *ND,
253*67e74705SXin Li                                                 SourceLocation ImplLoc,
254*67e74705SXin Li                                                 int select) {
255*67e74705SXin Li   if (ND && ND->isDeprecated()) {
256*67e74705SXin Li     S.Diag(ImplLoc, diag::warn_deprecated_def) << select;
257*67e74705SXin Li     if (select == 0)
258*67e74705SXin Li       S.Diag(ND->getLocation(), diag::note_method_declared_at)
259*67e74705SXin Li         << ND->getDeclName();
260*67e74705SXin Li     else
261*67e74705SXin Li       S.Diag(ND->getLocation(), diag::note_previous_decl) << "class";
262*67e74705SXin Li   }
263*67e74705SXin Li }
264*67e74705SXin Li 
265*67e74705SXin Li /// AddAnyMethodToGlobalPool - Add any method, instance or factory to global
266*67e74705SXin Li /// pool.
AddAnyMethodToGlobalPool(Decl * D)267*67e74705SXin Li void Sema::AddAnyMethodToGlobalPool(Decl *D) {
268*67e74705SXin Li   ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
269*67e74705SXin Li 
270*67e74705SXin Li   // If we don't have a valid method decl, simply return.
271*67e74705SXin Li   if (!MDecl)
272*67e74705SXin Li     return;
273*67e74705SXin Li   if (MDecl->isInstanceMethod())
274*67e74705SXin Li     AddInstanceMethodToGlobalPool(MDecl, true);
275*67e74705SXin Li   else
276*67e74705SXin Li     AddFactoryMethodToGlobalPool(MDecl, true);
277*67e74705SXin Li }
278*67e74705SXin Li 
279*67e74705SXin Li /// HasExplicitOwnershipAttr - returns true when pointer to ObjC pointer
280*67e74705SXin Li /// has explicit ownership attribute; false otherwise.
281*67e74705SXin Li static bool
HasExplicitOwnershipAttr(Sema & S,ParmVarDecl * Param)282*67e74705SXin Li HasExplicitOwnershipAttr(Sema &S, ParmVarDecl *Param) {
283*67e74705SXin Li   QualType T = Param->getType();
284*67e74705SXin Li 
285*67e74705SXin Li   if (const PointerType *PT = T->getAs<PointerType>()) {
286*67e74705SXin Li     T = PT->getPointeeType();
287*67e74705SXin Li   } else if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
288*67e74705SXin Li     T = RT->getPointeeType();
289*67e74705SXin Li   } else {
290*67e74705SXin Li     return true;
291*67e74705SXin Li   }
292*67e74705SXin Li 
293*67e74705SXin Li   // If we have a lifetime qualifier, but it's local, we must have
294*67e74705SXin Li   // inferred it. So, it is implicit.
295*67e74705SXin Li   return !T.getLocalQualifiers().hasObjCLifetime();
296*67e74705SXin Li }
297*67e74705SXin Li 
298*67e74705SXin Li /// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
299*67e74705SXin Li /// and user declared, in the method definition's AST.
ActOnStartOfObjCMethodDef(Scope * FnBodyScope,Decl * D)300*67e74705SXin Li void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
301*67e74705SXin Li   assert((getCurMethodDecl() == nullptr) && "Methodparsing confused");
302*67e74705SXin Li   ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
303*67e74705SXin Li 
304*67e74705SXin Li   // If we don't have a valid method decl, simply return.
305*67e74705SXin Li   if (!MDecl)
306*67e74705SXin Li     return;
307*67e74705SXin Li 
308*67e74705SXin Li   // Allow all of Sema to see that we are entering a method definition.
309*67e74705SXin Li   PushDeclContext(FnBodyScope, MDecl);
310*67e74705SXin Li   PushFunctionScope();
311*67e74705SXin Li 
312*67e74705SXin Li   // Create Decl objects for each parameter, entrring them in the scope for
313*67e74705SXin Li   // binding to their use.
314*67e74705SXin Li 
315*67e74705SXin Li   // Insert the invisible arguments, self and _cmd!
316*67e74705SXin Li   MDecl->createImplicitParams(Context, MDecl->getClassInterface());
317*67e74705SXin Li 
318*67e74705SXin Li   PushOnScopeChains(MDecl->getSelfDecl(), FnBodyScope);
319*67e74705SXin Li   PushOnScopeChains(MDecl->getCmdDecl(), FnBodyScope);
320*67e74705SXin Li 
321*67e74705SXin Li   // The ObjC parser requires parameter names so there's no need to check.
322*67e74705SXin Li   CheckParmsForFunctionDef(MDecl->parameters(),
323*67e74705SXin Li                            /*CheckParameterNames=*/false);
324*67e74705SXin Li 
325*67e74705SXin Li   // Introduce all of the other parameters into this scope.
326*67e74705SXin Li   for (auto *Param : MDecl->parameters()) {
327*67e74705SXin Li     if (!Param->isInvalidDecl() &&
328*67e74705SXin Li         getLangOpts().ObjCAutoRefCount &&
329*67e74705SXin Li         !HasExplicitOwnershipAttr(*this, Param))
330*67e74705SXin Li       Diag(Param->getLocation(), diag::warn_arc_strong_pointer_objc_pointer) <<
331*67e74705SXin Li             Param->getType();
332*67e74705SXin Li 
333*67e74705SXin Li     if (Param->getIdentifier())
334*67e74705SXin Li       PushOnScopeChains(Param, FnBodyScope);
335*67e74705SXin Li   }
336*67e74705SXin Li 
337*67e74705SXin Li   // In ARC, disallow definition of retain/release/autorelease/retainCount
338*67e74705SXin Li   if (getLangOpts().ObjCAutoRefCount) {
339*67e74705SXin Li     switch (MDecl->getMethodFamily()) {
340*67e74705SXin Li     case OMF_retain:
341*67e74705SXin Li     case OMF_retainCount:
342*67e74705SXin Li     case OMF_release:
343*67e74705SXin Li     case OMF_autorelease:
344*67e74705SXin Li       Diag(MDecl->getLocation(), diag::err_arc_illegal_method_def)
345*67e74705SXin Li         << 0 << MDecl->getSelector();
346*67e74705SXin Li       break;
347*67e74705SXin Li 
348*67e74705SXin Li     case OMF_None:
349*67e74705SXin Li     case OMF_dealloc:
350*67e74705SXin Li     case OMF_finalize:
351*67e74705SXin Li     case OMF_alloc:
352*67e74705SXin Li     case OMF_init:
353*67e74705SXin Li     case OMF_mutableCopy:
354*67e74705SXin Li     case OMF_copy:
355*67e74705SXin Li     case OMF_new:
356*67e74705SXin Li     case OMF_self:
357*67e74705SXin Li     case OMF_initialize:
358*67e74705SXin Li     case OMF_performSelector:
359*67e74705SXin Li       break;
360*67e74705SXin Li     }
361*67e74705SXin Li   }
362*67e74705SXin Li 
363*67e74705SXin Li   // Warn on deprecated methods under -Wdeprecated-implementations,
364*67e74705SXin Li   // and prepare for warning on missing super calls.
365*67e74705SXin Li   if (ObjCInterfaceDecl *IC = MDecl->getClassInterface()) {
366*67e74705SXin Li     ObjCMethodDecl *IMD =
367*67e74705SXin Li       IC->lookupMethod(MDecl->getSelector(), MDecl->isInstanceMethod());
368*67e74705SXin Li 
369*67e74705SXin Li     if (IMD) {
370*67e74705SXin Li       ObjCImplDecl *ImplDeclOfMethodDef =
371*67e74705SXin Li         dyn_cast<ObjCImplDecl>(MDecl->getDeclContext());
372*67e74705SXin Li       ObjCContainerDecl *ContDeclOfMethodDecl =
373*67e74705SXin Li         dyn_cast<ObjCContainerDecl>(IMD->getDeclContext());
374*67e74705SXin Li       ObjCImplDecl *ImplDeclOfMethodDecl = nullptr;
375*67e74705SXin Li       if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ContDeclOfMethodDecl))
376*67e74705SXin Li         ImplDeclOfMethodDecl = OID->getImplementation();
377*67e74705SXin Li       else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(ContDeclOfMethodDecl)) {
378*67e74705SXin Li         if (CD->IsClassExtension()) {
379*67e74705SXin Li           if (ObjCInterfaceDecl *OID = CD->getClassInterface())
380*67e74705SXin Li             ImplDeclOfMethodDecl = OID->getImplementation();
381*67e74705SXin Li         } else
382*67e74705SXin Li             ImplDeclOfMethodDecl = CD->getImplementation();
383*67e74705SXin Li       }
384*67e74705SXin Li       // No need to issue deprecated warning if deprecated mehod in class/category
385*67e74705SXin Li       // is being implemented in its own implementation (no overriding is involved).
386*67e74705SXin Li       if (!ImplDeclOfMethodDecl || ImplDeclOfMethodDecl != ImplDeclOfMethodDef)
387*67e74705SXin Li         DiagnoseObjCImplementedDeprecations(*this,
388*67e74705SXin Li                                           dyn_cast<NamedDecl>(IMD),
389*67e74705SXin Li                                           MDecl->getLocation(), 0);
390*67e74705SXin Li     }
391*67e74705SXin Li 
392*67e74705SXin Li     if (MDecl->getMethodFamily() == OMF_init) {
393*67e74705SXin Li       if (MDecl->isDesignatedInitializerForTheInterface()) {
394*67e74705SXin Li         getCurFunction()->ObjCIsDesignatedInit = true;
395*67e74705SXin Li         getCurFunction()->ObjCWarnForNoDesignatedInitChain =
396*67e74705SXin Li             IC->getSuperClass() != nullptr;
397*67e74705SXin Li       } else if (IC->hasDesignatedInitializers()) {
398*67e74705SXin Li         getCurFunction()->ObjCIsSecondaryInit = true;
399*67e74705SXin Li         getCurFunction()->ObjCWarnForNoInitDelegation = true;
400*67e74705SXin Li       }
401*67e74705SXin Li     }
402*67e74705SXin Li 
403*67e74705SXin Li     // If this is "dealloc" or "finalize", set some bit here.
404*67e74705SXin Li     // Then in ActOnSuperMessage() (SemaExprObjC), set it back to false.
405*67e74705SXin Li     // Finally, in ActOnFinishFunctionBody() (SemaDecl), warn if flag is set.
406*67e74705SXin Li     // Only do this if the current class actually has a superclass.
407*67e74705SXin Li     if (const ObjCInterfaceDecl *SuperClass = IC->getSuperClass()) {
408*67e74705SXin Li       ObjCMethodFamily Family = MDecl->getMethodFamily();
409*67e74705SXin Li       if (Family == OMF_dealloc) {
410*67e74705SXin Li         if (!(getLangOpts().ObjCAutoRefCount ||
411*67e74705SXin Li               getLangOpts().getGC() == LangOptions::GCOnly))
412*67e74705SXin Li           getCurFunction()->ObjCShouldCallSuper = true;
413*67e74705SXin Li 
414*67e74705SXin Li       } else if (Family == OMF_finalize) {
415*67e74705SXin Li         if (Context.getLangOpts().getGC() != LangOptions::NonGC)
416*67e74705SXin Li           getCurFunction()->ObjCShouldCallSuper = true;
417*67e74705SXin Li 
418*67e74705SXin Li       } else {
419*67e74705SXin Li         const ObjCMethodDecl *SuperMethod =
420*67e74705SXin Li           SuperClass->lookupMethod(MDecl->getSelector(),
421*67e74705SXin Li                                    MDecl->isInstanceMethod());
422*67e74705SXin Li         getCurFunction()->ObjCShouldCallSuper =
423*67e74705SXin Li           (SuperMethod && SuperMethod->hasAttr<ObjCRequiresSuperAttr>());
424*67e74705SXin Li       }
425*67e74705SXin Li     }
426*67e74705SXin Li   }
427*67e74705SXin Li }
428*67e74705SXin Li 
429*67e74705SXin Li namespace {
430*67e74705SXin Li 
431*67e74705SXin Li // Callback to only accept typo corrections that are Objective-C classes.
432*67e74705SXin Li // If an ObjCInterfaceDecl* is given to the constructor, then the validation
433*67e74705SXin Li // function will reject corrections to that class.
434*67e74705SXin Li class ObjCInterfaceValidatorCCC : public CorrectionCandidateCallback {
435*67e74705SXin Li  public:
ObjCInterfaceValidatorCCC()436*67e74705SXin Li   ObjCInterfaceValidatorCCC() : CurrentIDecl(nullptr) {}
ObjCInterfaceValidatorCCC(ObjCInterfaceDecl * IDecl)437*67e74705SXin Li   explicit ObjCInterfaceValidatorCCC(ObjCInterfaceDecl *IDecl)
438*67e74705SXin Li       : CurrentIDecl(IDecl) {}
439*67e74705SXin Li 
ValidateCandidate(const TypoCorrection & candidate)440*67e74705SXin Li   bool ValidateCandidate(const TypoCorrection &candidate) override {
441*67e74705SXin Li     ObjCInterfaceDecl *ID = candidate.getCorrectionDeclAs<ObjCInterfaceDecl>();
442*67e74705SXin Li     return ID && !declaresSameEntity(ID, CurrentIDecl);
443*67e74705SXin Li   }
444*67e74705SXin Li 
445*67e74705SXin Li  private:
446*67e74705SXin Li   ObjCInterfaceDecl *CurrentIDecl;
447*67e74705SXin Li };
448*67e74705SXin Li 
449*67e74705SXin Li } // end anonymous namespace
450*67e74705SXin Li 
diagnoseUseOfProtocols(Sema & TheSema,ObjCContainerDecl * CD,ObjCProtocolDecl * const * ProtoRefs,unsigned NumProtoRefs,const SourceLocation * ProtoLocs)451*67e74705SXin Li static void diagnoseUseOfProtocols(Sema &TheSema,
452*67e74705SXin Li                                    ObjCContainerDecl *CD,
453*67e74705SXin Li                                    ObjCProtocolDecl *const *ProtoRefs,
454*67e74705SXin Li                                    unsigned NumProtoRefs,
455*67e74705SXin Li                                    const SourceLocation *ProtoLocs) {
456*67e74705SXin Li   assert(ProtoRefs);
457*67e74705SXin Li   // Diagnose availability in the context of the ObjC container.
458*67e74705SXin Li   Sema::ContextRAII SavedContext(TheSema, CD);
459*67e74705SXin Li   for (unsigned i = 0; i < NumProtoRefs; ++i) {
460*67e74705SXin Li     (void)TheSema.DiagnoseUseOfDecl(ProtoRefs[i], ProtoLocs[i]);
461*67e74705SXin Li   }
462*67e74705SXin Li }
463*67e74705SXin Li 
464*67e74705SXin Li void Sema::
ActOnSuperClassOfClassInterface(Scope * S,SourceLocation AtInterfaceLoc,ObjCInterfaceDecl * IDecl,IdentifierInfo * ClassName,SourceLocation ClassLoc,IdentifierInfo * SuperName,SourceLocation SuperLoc,ArrayRef<ParsedType> SuperTypeArgs,SourceRange SuperTypeArgsRange)465*67e74705SXin Li ActOnSuperClassOfClassInterface(Scope *S,
466*67e74705SXin Li                                 SourceLocation AtInterfaceLoc,
467*67e74705SXin Li                                 ObjCInterfaceDecl *IDecl,
468*67e74705SXin Li                                 IdentifierInfo *ClassName,
469*67e74705SXin Li                                 SourceLocation ClassLoc,
470*67e74705SXin Li                                 IdentifierInfo *SuperName,
471*67e74705SXin Li                                 SourceLocation SuperLoc,
472*67e74705SXin Li                                 ArrayRef<ParsedType> SuperTypeArgs,
473*67e74705SXin Li                                 SourceRange SuperTypeArgsRange) {
474*67e74705SXin Li   // Check if a different kind of symbol declared in this scope.
475*67e74705SXin Li   NamedDecl *PrevDecl = LookupSingleName(TUScope, SuperName, SuperLoc,
476*67e74705SXin Li                                          LookupOrdinaryName);
477*67e74705SXin Li 
478*67e74705SXin Li   if (!PrevDecl) {
479*67e74705SXin Li     // Try to correct for a typo in the superclass name without correcting
480*67e74705SXin Li     // to the class we're defining.
481*67e74705SXin Li     if (TypoCorrection Corrected = CorrectTypo(
482*67e74705SXin Li             DeclarationNameInfo(SuperName, SuperLoc),
483*67e74705SXin Li             LookupOrdinaryName, TUScope,
484*67e74705SXin Li             nullptr, llvm::make_unique<ObjCInterfaceValidatorCCC>(IDecl),
485*67e74705SXin Li             CTK_ErrorRecovery)) {
486*67e74705SXin Li       diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest)
487*67e74705SXin Li                    << SuperName << ClassName);
488*67e74705SXin Li       PrevDecl = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>();
489*67e74705SXin Li     }
490*67e74705SXin Li   }
491*67e74705SXin Li 
492*67e74705SXin Li   if (declaresSameEntity(PrevDecl, IDecl)) {
493*67e74705SXin Li     Diag(SuperLoc, diag::err_recursive_superclass)
494*67e74705SXin Li       << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
495*67e74705SXin Li     IDecl->setEndOfDefinitionLoc(ClassLoc);
496*67e74705SXin Li   } else {
497*67e74705SXin Li     ObjCInterfaceDecl *SuperClassDecl =
498*67e74705SXin Li     dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
499*67e74705SXin Li     QualType SuperClassType;
500*67e74705SXin Li 
501*67e74705SXin Li     // Diagnose classes that inherit from deprecated classes.
502*67e74705SXin Li     if (SuperClassDecl) {
503*67e74705SXin Li       (void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc);
504*67e74705SXin Li       SuperClassType = Context.getObjCInterfaceType(SuperClassDecl);
505*67e74705SXin Li     }
506*67e74705SXin Li 
507*67e74705SXin Li     if (PrevDecl && !SuperClassDecl) {
508*67e74705SXin Li       // The previous declaration was not a class decl. Check if we have a
509*67e74705SXin Li       // typedef. If we do, get the underlying class type.
510*67e74705SXin Li       if (const TypedefNameDecl *TDecl =
511*67e74705SXin Li           dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) {
512*67e74705SXin Li         QualType T = TDecl->getUnderlyingType();
513*67e74705SXin Li         if (T->isObjCObjectType()) {
514*67e74705SXin Li           if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface()) {
515*67e74705SXin Li             SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
516*67e74705SXin Li             SuperClassType = Context.getTypeDeclType(TDecl);
517*67e74705SXin Li 
518*67e74705SXin Li             // This handles the following case:
519*67e74705SXin Li             // @interface NewI @end
520*67e74705SXin Li             // typedef NewI DeprI __attribute__((deprecated("blah")))
521*67e74705SXin Li             // @interface SI : DeprI /* warn here */ @end
522*67e74705SXin Li             (void)DiagnoseUseOfDecl(const_cast<TypedefNameDecl*>(TDecl), SuperLoc);
523*67e74705SXin Li           }
524*67e74705SXin Li         }
525*67e74705SXin Li       }
526*67e74705SXin Li 
527*67e74705SXin Li       // This handles the following case:
528*67e74705SXin Li       //
529*67e74705SXin Li       // typedef int SuperClass;
530*67e74705SXin Li       // @interface MyClass : SuperClass {} @end
531*67e74705SXin Li       //
532*67e74705SXin Li       if (!SuperClassDecl) {
533*67e74705SXin Li         Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
534*67e74705SXin Li         Diag(PrevDecl->getLocation(), diag::note_previous_definition);
535*67e74705SXin Li       }
536*67e74705SXin Li     }
537*67e74705SXin Li 
538*67e74705SXin Li     if (!dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) {
539*67e74705SXin Li       if (!SuperClassDecl)
540*67e74705SXin Li         Diag(SuperLoc, diag::err_undef_superclass)
541*67e74705SXin Li           << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
542*67e74705SXin Li       else if (RequireCompleteType(SuperLoc,
543*67e74705SXin Li                                    SuperClassType,
544*67e74705SXin Li                                    diag::err_forward_superclass,
545*67e74705SXin Li                                    SuperClassDecl->getDeclName(),
546*67e74705SXin Li                                    ClassName,
547*67e74705SXin Li                                    SourceRange(AtInterfaceLoc, ClassLoc))) {
548*67e74705SXin Li         SuperClassDecl = nullptr;
549*67e74705SXin Li         SuperClassType = QualType();
550*67e74705SXin Li       }
551*67e74705SXin Li     }
552*67e74705SXin Li 
553*67e74705SXin Li     if (SuperClassType.isNull()) {
554*67e74705SXin Li       assert(!SuperClassDecl && "Failed to set SuperClassType?");
555*67e74705SXin Li       return;
556*67e74705SXin Li     }
557*67e74705SXin Li 
558*67e74705SXin Li     // Handle type arguments on the superclass.
559*67e74705SXin Li     TypeSourceInfo *SuperClassTInfo = nullptr;
560*67e74705SXin Li     if (!SuperTypeArgs.empty()) {
561*67e74705SXin Li       TypeResult fullSuperClassType = actOnObjCTypeArgsAndProtocolQualifiers(
562*67e74705SXin Li                                         S,
563*67e74705SXin Li                                         SuperLoc,
564*67e74705SXin Li                                         CreateParsedType(SuperClassType,
565*67e74705SXin Li                                                          nullptr),
566*67e74705SXin Li                                         SuperTypeArgsRange.getBegin(),
567*67e74705SXin Li                                         SuperTypeArgs,
568*67e74705SXin Li                                         SuperTypeArgsRange.getEnd(),
569*67e74705SXin Li                                         SourceLocation(),
570*67e74705SXin Li                                         { },
571*67e74705SXin Li                                         { },
572*67e74705SXin Li                                         SourceLocation());
573*67e74705SXin Li       if (!fullSuperClassType.isUsable())
574*67e74705SXin Li         return;
575*67e74705SXin Li 
576*67e74705SXin Li       SuperClassType = GetTypeFromParser(fullSuperClassType.get(),
577*67e74705SXin Li                                          &SuperClassTInfo);
578*67e74705SXin Li     }
579*67e74705SXin Li 
580*67e74705SXin Li     if (!SuperClassTInfo) {
581*67e74705SXin Li       SuperClassTInfo = Context.getTrivialTypeSourceInfo(SuperClassType,
582*67e74705SXin Li                                                          SuperLoc);
583*67e74705SXin Li     }
584*67e74705SXin Li 
585*67e74705SXin Li     IDecl->setSuperClass(SuperClassTInfo);
586*67e74705SXin Li     IDecl->setEndOfDefinitionLoc(SuperClassTInfo->getTypeLoc().getLocEnd());
587*67e74705SXin Li   }
588*67e74705SXin Li }
589*67e74705SXin Li 
actOnObjCTypeParam(Scope * S,ObjCTypeParamVariance variance,SourceLocation varianceLoc,unsigned index,IdentifierInfo * paramName,SourceLocation paramLoc,SourceLocation colonLoc,ParsedType parsedTypeBound)590*67e74705SXin Li DeclResult Sema::actOnObjCTypeParam(Scope *S,
591*67e74705SXin Li                                     ObjCTypeParamVariance variance,
592*67e74705SXin Li                                     SourceLocation varianceLoc,
593*67e74705SXin Li                                     unsigned index,
594*67e74705SXin Li                                     IdentifierInfo *paramName,
595*67e74705SXin Li                                     SourceLocation paramLoc,
596*67e74705SXin Li                                     SourceLocation colonLoc,
597*67e74705SXin Li                                     ParsedType parsedTypeBound) {
598*67e74705SXin Li   // If there was an explicitly-provided type bound, check it.
599*67e74705SXin Li   TypeSourceInfo *typeBoundInfo = nullptr;
600*67e74705SXin Li   if (parsedTypeBound) {
601*67e74705SXin Li     // The type bound can be any Objective-C pointer type.
602*67e74705SXin Li     QualType typeBound = GetTypeFromParser(parsedTypeBound, &typeBoundInfo);
603*67e74705SXin Li     if (typeBound->isObjCObjectPointerType()) {
604*67e74705SXin Li       // okay
605*67e74705SXin Li     } else if (typeBound->isObjCObjectType()) {
606*67e74705SXin Li       // The user forgot the * on an Objective-C pointer type, e.g.,
607*67e74705SXin Li       // "T : NSView".
608*67e74705SXin Li       SourceLocation starLoc = getLocForEndOfToken(
609*67e74705SXin Li                                  typeBoundInfo->getTypeLoc().getEndLoc());
610*67e74705SXin Li       Diag(typeBoundInfo->getTypeLoc().getBeginLoc(),
611*67e74705SXin Li            diag::err_objc_type_param_bound_missing_pointer)
612*67e74705SXin Li         << typeBound << paramName
613*67e74705SXin Li         << FixItHint::CreateInsertion(starLoc, " *");
614*67e74705SXin Li 
615*67e74705SXin Li       // Create a new type location builder so we can update the type
616*67e74705SXin Li       // location information we have.
617*67e74705SXin Li       TypeLocBuilder builder;
618*67e74705SXin Li       builder.pushFullCopy(typeBoundInfo->getTypeLoc());
619*67e74705SXin Li 
620*67e74705SXin Li       // Create the Objective-C pointer type.
621*67e74705SXin Li       typeBound = Context.getObjCObjectPointerType(typeBound);
622*67e74705SXin Li       ObjCObjectPointerTypeLoc newT
623*67e74705SXin Li         = builder.push<ObjCObjectPointerTypeLoc>(typeBound);
624*67e74705SXin Li       newT.setStarLoc(starLoc);
625*67e74705SXin Li 
626*67e74705SXin Li       // Form the new type source information.
627*67e74705SXin Li       typeBoundInfo = builder.getTypeSourceInfo(Context, typeBound);
628*67e74705SXin Li     } else {
629*67e74705SXin Li       // Not a valid type bound.
630*67e74705SXin Li       Diag(typeBoundInfo->getTypeLoc().getBeginLoc(),
631*67e74705SXin Li            diag::err_objc_type_param_bound_nonobject)
632*67e74705SXin Li         << typeBound << paramName;
633*67e74705SXin Li 
634*67e74705SXin Li       // Forget the bound; we'll default to id later.
635*67e74705SXin Li       typeBoundInfo = nullptr;
636*67e74705SXin Li     }
637*67e74705SXin Li 
638*67e74705SXin Li     // Type bounds cannot have qualifiers (even indirectly) or explicit
639*67e74705SXin Li     // nullability.
640*67e74705SXin Li     if (typeBoundInfo) {
641*67e74705SXin Li       QualType typeBound = typeBoundInfo->getType();
642*67e74705SXin Li       TypeLoc qual = typeBoundInfo->getTypeLoc().findExplicitQualifierLoc();
643*67e74705SXin Li       if (qual || typeBound.hasQualifiers()) {
644*67e74705SXin Li         bool diagnosed = false;
645*67e74705SXin Li         SourceRange rangeToRemove;
646*67e74705SXin Li         if (qual) {
647*67e74705SXin Li           if (auto attr = qual.getAs<AttributedTypeLoc>()) {
648*67e74705SXin Li             rangeToRemove = attr.getLocalSourceRange();
649*67e74705SXin Li             if (attr.getTypePtr()->getImmediateNullability()) {
650*67e74705SXin Li               Diag(attr.getLocStart(),
651*67e74705SXin Li                    diag::err_objc_type_param_bound_explicit_nullability)
652*67e74705SXin Li                 << paramName << typeBound
653*67e74705SXin Li                 << FixItHint::CreateRemoval(rangeToRemove);
654*67e74705SXin Li               diagnosed = true;
655*67e74705SXin Li             }
656*67e74705SXin Li           }
657*67e74705SXin Li         }
658*67e74705SXin Li 
659*67e74705SXin Li         if (!diagnosed) {
660*67e74705SXin Li           Diag(qual ? qual.getLocStart()
661*67e74705SXin Li                     : typeBoundInfo->getTypeLoc().getLocStart(),
662*67e74705SXin Li               diag::err_objc_type_param_bound_qualified)
663*67e74705SXin Li             << paramName << typeBound << typeBound.getQualifiers().getAsString()
664*67e74705SXin Li             << FixItHint::CreateRemoval(rangeToRemove);
665*67e74705SXin Li         }
666*67e74705SXin Li 
667*67e74705SXin Li         // If the type bound has qualifiers other than CVR, we need to strip
668*67e74705SXin Li         // them or we'll probably assert later when trying to apply new
669*67e74705SXin Li         // qualifiers.
670*67e74705SXin Li         Qualifiers quals = typeBound.getQualifiers();
671*67e74705SXin Li         quals.removeCVRQualifiers();
672*67e74705SXin Li         if (!quals.empty()) {
673*67e74705SXin Li           typeBoundInfo =
674*67e74705SXin Li              Context.getTrivialTypeSourceInfo(typeBound.getUnqualifiedType());
675*67e74705SXin Li         }
676*67e74705SXin Li       }
677*67e74705SXin Li     }
678*67e74705SXin Li   }
679*67e74705SXin Li 
680*67e74705SXin Li   // If there was no explicit type bound (or we removed it due to an error),
681*67e74705SXin Li   // use 'id' instead.
682*67e74705SXin Li   if (!typeBoundInfo) {
683*67e74705SXin Li     colonLoc = SourceLocation();
684*67e74705SXin Li     typeBoundInfo = Context.getTrivialTypeSourceInfo(Context.getObjCIdType());
685*67e74705SXin Li   }
686*67e74705SXin Li 
687*67e74705SXin Li   // Create the type parameter.
688*67e74705SXin Li   return ObjCTypeParamDecl::Create(Context, CurContext, variance, varianceLoc,
689*67e74705SXin Li                                    index, paramLoc, paramName, colonLoc,
690*67e74705SXin Li                                    typeBoundInfo);
691*67e74705SXin Li }
692*67e74705SXin Li 
actOnObjCTypeParamList(Scope * S,SourceLocation lAngleLoc,ArrayRef<Decl * > typeParamsIn,SourceLocation rAngleLoc)693*67e74705SXin Li ObjCTypeParamList *Sema::actOnObjCTypeParamList(Scope *S,
694*67e74705SXin Li                                                 SourceLocation lAngleLoc,
695*67e74705SXin Li                                                 ArrayRef<Decl *> typeParamsIn,
696*67e74705SXin Li                                                 SourceLocation rAngleLoc) {
697*67e74705SXin Li   // We know that the array only contains Objective-C type parameters.
698*67e74705SXin Li   ArrayRef<ObjCTypeParamDecl *>
699*67e74705SXin Li     typeParams(
700*67e74705SXin Li       reinterpret_cast<ObjCTypeParamDecl * const *>(typeParamsIn.data()),
701*67e74705SXin Li       typeParamsIn.size());
702*67e74705SXin Li 
703*67e74705SXin Li   // Diagnose redeclarations of type parameters.
704*67e74705SXin Li   // We do this now because Objective-C type parameters aren't pushed into
705*67e74705SXin Li   // scope until later (after the instance variable block), but we want the
706*67e74705SXin Li   // diagnostics to occur right after we parse the type parameter list.
707*67e74705SXin Li   llvm::SmallDenseMap<IdentifierInfo *, ObjCTypeParamDecl *> knownParams;
708*67e74705SXin Li   for (auto typeParam : typeParams) {
709*67e74705SXin Li     auto known = knownParams.find(typeParam->getIdentifier());
710*67e74705SXin Li     if (known != knownParams.end()) {
711*67e74705SXin Li       Diag(typeParam->getLocation(), diag::err_objc_type_param_redecl)
712*67e74705SXin Li         << typeParam->getIdentifier()
713*67e74705SXin Li         << SourceRange(known->second->getLocation());
714*67e74705SXin Li 
715*67e74705SXin Li       typeParam->setInvalidDecl();
716*67e74705SXin Li     } else {
717*67e74705SXin Li       knownParams.insert(std::make_pair(typeParam->getIdentifier(), typeParam));
718*67e74705SXin Li 
719*67e74705SXin Li       // Push the type parameter into scope.
720*67e74705SXin Li       PushOnScopeChains(typeParam, S, /*AddToContext=*/false);
721*67e74705SXin Li     }
722*67e74705SXin Li   }
723*67e74705SXin Li 
724*67e74705SXin Li   // Create the parameter list.
725*67e74705SXin Li   return ObjCTypeParamList::create(Context, lAngleLoc, typeParams, rAngleLoc);
726*67e74705SXin Li }
727*67e74705SXin Li 
popObjCTypeParamList(Scope * S,ObjCTypeParamList * typeParamList)728*67e74705SXin Li void Sema::popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList) {
729*67e74705SXin Li   for (auto typeParam : *typeParamList) {
730*67e74705SXin Li     if (!typeParam->isInvalidDecl()) {
731*67e74705SXin Li       S->RemoveDecl(typeParam);
732*67e74705SXin Li       IdResolver.RemoveDecl(typeParam);
733*67e74705SXin Li     }
734*67e74705SXin Li   }
735*67e74705SXin Li }
736*67e74705SXin Li 
737*67e74705SXin Li namespace {
738*67e74705SXin Li   /// The context in which an Objective-C type parameter list occurs, for use
739*67e74705SXin Li   /// in diagnostics.
740*67e74705SXin Li   enum class TypeParamListContext {
741*67e74705SXin Li     ForwardDeclaration,
742*67e74705SXin Li     Definition,
743*67e74705SXin Li     Category,
744*67e74705SXin Li     Extension
745*67e74705SXin Li   };
746*67e74705SXin Li } // end anonymous namespace
747*67e74705SXin Li 
748*67e74705SXin Li /// Check consistency between two Objective-C type parameter lists, e.g.,
749*67e74705SXin Li /// between a category/extension and an \@interface or between an \@class and an
750*67e74705SXin Li /// \@interface.
checkTypeParamListConsistency(Sema & S,ObjCTypeParamList * prevTypeParams,ObjCTypeParamList * newTypeParams,TypeParamListContext newContext)751*67e74705SXin Li static bool checkTypeParamListConsistency(Sema &S,
752*67e74705SXin Li                                           ObjCTypeParamList *prevTypeParams,
753*67e74705SXin Li                                           ObjCTypeParamList *newTypeParams,
754*67e74705SXin Li                                           TypeParamListContext newContext) {
755*67e74705SXin Li   // If the sizes don't match, complain about that.
756*67e74705SXin Li   if (prevTypeParams->size() != newTypeParams->size()) {
757*67e74705SXin Li     SourceLocation diagLoc;
758*67e74705SXin Li     if (newTypeParams->size() > prevTypeParams->size()) {
759*67e74705SXin Li       diagLoc = newTypeParams->begin()[prevTypeParams->size()]->getLocation();
760*67e74705SXin Li     } else {
761*67e74705SXin Li       diagLoc = S.getLocForEndOfToken(newTypeParams->back()->getLocEnd());
762*67e74705SXin Li     }
763*67e74705SXin Li 
764*67e74705SXin Li     S.Diag(diagLoc, diag::err_objc_type_param_arity_mismatch)
765*67e74705SXin Li       << static_cast<unsigned>(newContext)
766*67e74705SXin Li       << (newTypeParams->size() > prevTypeParams->size())
767*67e74705SXin Li       << prevTypeParams->size()
768*67e74705SXin Li       << newTypeParams->size();
769*67e74705SXin Li 
770*67e74705SXin Li     return true;
771*67e74705SXin Li   }
772*67e74705SXin Li 
773*67e74705SXin Li   // Match up the type parameters.
774*67e74705SXin Li   for (unsigned i = 0, n = prevTypeParams->size(); i != n; ++i) {
775*67e74705SXin Li     ObjCTypeParamDecl *prevTypeParam = prevTypeParams->begin()[i];
776*67e74705SXin Li     ObjCTypeParamDecl *newTypeParam = newTypeParams->begin()[i];
777*67e74705SXin Li 
778*67e74705SXin Li     // Check for consistency of the variance.
779*67e74705SXin Li     if (newTypeParam->getVariance() != prevTypeParam->getVariance()) {
780*67e74705SXin Li       if (newTypeParam->getVariance() == ObjCTypeParamVariance::Invariant &&
781*67e74705SXin Li           newContext != TypeParamListContext::Definition) {
782*67e74705SXin Li         // When the new type parameter is invariant and is not part
783*67e74705SXin Li         // of the definition, just propagate the variance.
784*67e74705SXin Li         newTypeParam->setVariance(prevTypeParam->getVariance());
785*67e74705SXin Li       } else if (prevTypeParam->getVariance()
786*67e74705SXin Li                    == ObjCTypeParamVariance::Invariant &&
787*67e74705SXin Li                  !(isa<ObjCInterfaceDecl>(prevTypeParam->getDeclContext()) &&
788*67e74705SXin Li                    cast<ObjCInterfaceDecl>(prevTypeParam->getDeclContext())
789*67e74705SXin Li                      ->getDefinition() == prevTypeParam->getDeclContext())) {
790*67e74705SXin Li         // When the old parameter is invariant and was not part of the
791*67e74705SXin Li         // definition, just ignore the difference because it doesn't
792*67e74705SXin Li         // matter.
793*67e74705SXin Li       } else {
794*67e74705SXin Li         {
795*67e74705SXin Li           // Diagnose the conflict and update the second declaration.
796*67e74705SXin Li           SourceLocation diagLoc = newTypeParam->getVarianceLoc();
797*67e74705SXin Li           if (diagLoc.isInvalid())
798*67e74705SXin Li             diagLoc = newTypeParam->getLocStart();
799*67e74705SXin Li 
800*67e74705SXin Li           auto diag = S.Diag(diagLoc,
801*67e74705SXin Li                              diag::err_objc_type_param_variance_conflict)
802*67e74705SXin Li                         << static_cast<unsigned>(newTypeParam->getVariance())
803*67e74705SXin Li                         << newTypeParam->getDeclName()
804*67e74705SXin Li                         << static_cast<unsigned>(prevTypeParam->getVariance())
805*67e74705SXin Li                         << prevTypeParam->getDeclName();
806*67e74705SXin Li           switch (prevTypeParam->getVariance()) {
807*67e74705SXin Li           case ObjCTypeParamVariance::Invariant:
808*67e74705SXin Li             diag << FixItHint::CreateRemoval(newTypeParam->getVarianceLoc());
809*67e74705SXin Li             break;
810*67e74705SXin Li 
811*67e74705SXin Li           case ObjCTypeParamVariance::Covariant:
812*67e74705SXin Li           case ObjCTypeParamVariance::Contravariant: {
813*67e74705SXin Li             StringRef newVarianceStr
814*67e74705SXin Li                = prevTypeParam->getVariance() == ObjCTypeParamVariance::Covariant
815*67e74705SXin Li                    ? "__covariant"
816*67e74705SXin Li                    : "__contravariant";
817*67e74705SXin Li             if (newTypeParam->getVariance()
818*67e74705SXin Li                   == ObjCTypeParamVariance::Invariant) {
819*67e74705SXin Li               diag << FixItHint::CreateInsertion(newTypeParam->getLocStart(),
820*67e74705SXin Li                                                  (newVarianceStr + " ").str());
821*67e74705SXin Li             } else {
822*67e74705SXin Li               diag << FixItHint::CreateReplacement(newTypeParam->getVarianceLoc(),
823*67e74705SXin Li                                                newVarianceStr);
824*67e74705SXin Li             }
825*67e74705SXin Li           }
826*67e74705SXin Li           }
827*67e74705SXin Li         }
828*67e74705SXin Li 
829*67e74705SXin Li         S.Diag(prevTypeParam->getLocation(), diag::note_objc_type_param_here)
830*67e74705SXin Li           << prevTypeParam->getDeclName();
831*67e74705SXin Li 
832*67e74705SXin Li         // Override the variance.
833*67e74705SXin Li         newTypeParam->setVariance(prevTypeParam->getVariance());
834*67e74705SXin Li       }
835*67e74705SXin Li     }
836*67e74705SXin Li 
837*67e74705SXin Li     // If the bound types match, there's nothing to do.
838*67e74705SXin Li     if (S.Context.hasSameType(prevTypeParam->getUnderlyingType(),
839*67e74705SXin Li                               newTypeParam->getUnderlyingType()))
840*67e74705SXin Li       continue;
841*67e74705SXin Li 
842*67e74705SXin Li     // If the new type parameter's bound was explicit, complain about it being
843*67e74705SXin Li     // different from the original.
844*67e74705SXin Li     if (newTypeParam->hasExplicitBound()) {
845*67e74705SXin Li       SourceRange newBoundRange = newTypeParam->getTypeSourceInfo()
846*67e74705SXin Li                                     ->getTypeLoc().getSourceRange();
847*67e74705SXin Li       S.Diag(newBoundRange.getBegin(), diag::err_objc_type_param_bound_conflict)
848*67e74705SXin Li         << newTypeParam->getUnderlyingType()
849*67e74705SXin Li         << newTypeParam->getDeclName()
850*67e74705SXin Li         << prevTypeParam->hasExplicitBound()
851*67e74705SXin Li         << prevTypeParam->getUnderlyingType()
852*67e74705SXin Li         << (newTypeParam->getDeclName() == prevTypeParam->getDeclName())
853*67e74705SXin Li         << prevTypeParam->getDeclName()
854*67e74705SXin Li         << FixItHint::CreateReplacement(
855*67e74705SXin Li              newBoundRange,
856*67e74705SXin Li              prevTypeParam->getUnderlyingType().getAsString(
857*67e74705SXin Li                S.Context.getPrintingPolicy()));
858*67e74705SXin Li 
859*67e74705SXin Li       S.Diag(prevTypeParam->getLocation(), diag::note_objc_type_param_here)
860*67e74705SXin Li         << prevTypeParam->getDeclName();
861*67e74705SXin Li 
862*67e74705SXin Li       // Override the new type parameter's bound type with the previous type,
863*67e74705SXin Li       // so that it's consistent.
864*67e74705SXin Li       newTypeParam->setTypeSourceInfo(
865*67e74705SXin Li         S.Context.getTrivialTypeSourceInfo(prevTypeParam->getUnderlyingType()));
866*67e74705SXin Li       continue;
867*67e74705SXin Li     }
868*67e74705SXin Li 
869*67e74705SXin Li     // The new type parameter got the implicit bound of 'id'. That's okay for
870*67e74705SXin Li     // categories and extensions (overwrite it later), but not for forward
871*67e74705SXin Li     // declarations and @interfaces, because those must be standalone.
872*67e74705SXin Li     if (newContext == TypeParamListContext::ForwardDeclaration ||
873*67e74705SXin Li         newContext == TypeParamListContext::Definition) {
874*67e74705SXin Li       // Diagnose this problem for forward declarations and definitions.
875*67e74705SXin Li       SourceLocation insertionLoc
876*67e74705SXin Li         = S.getLocForEndOfToken(newTypeParam->getLocation());
877*67e74705SXin Li       std::string newCode
878*67e74705SXin Li         = " : " + prevTypeParam->getUnderlyingType().getAsString(
879*67e74705SXin Li                     S.Context.getPrintingPolicy());
880*67e74705SXin Li       S.Diag(newTypeParam->getLocation(),
881*67e74705SXin Li              diag::err_objc_type_param_bound_missing)
882*67e74705SXin Li         << prevTypeParam->getUnderlyingType()
883*67e74705SXin Li         << newTypeParam->getDeclName()
884*67e74705SXin Li         << (newContext == TypeParamListContext::ForwardDeclaration)
885*67e74705SXin Li         << FixItHint::CreateInsertion(insertionLoc, newCode);
886*67e74705SXin Li 
887*67e74705SXin Li       S.Diag(prevTypeParam->getLocation(), diag::note_objc_type_param_here)
888*67e74705SXin Li         << prevTypeParam->getDeclName();
889*67e74705SXin Li     }
890*67e74705SXin Li 
891*67e74705SXin Li     // Update the new type parameter's bound to match the previous one.
892*67e74705SXin Li     newTypeParam->setTypeSourceInfo(
893*67e74705SXin Li       S.Context.getTrivialTypeSourceInfo(prevTypeParam->getUnderlyingType()));
894*67e74705SXin Li   }
895*67e74705SXin Li 
896*67e74705SXin Li   return false;
897*67e74705SXin Li }
898*67e74705SXin Li 
899*67e74705SXin Li Decl *Sema::
ActOnStartClassInterface(Scope * S,SourceLocation AtInterfaceLoc,IdentifierInfo * ClassName,SourceLocation ClassLoc,ObjCTypeParamList * typeParamList,IdentifierInfo * SuperName,SourceLocation SuperLoc,ArrayRef<ParsedType> SuperTypeArgs,SourceRange SuperTypeArgsRange,Decl * const * ProtoRefs,unsigned NumProtoRefs,const SourceLocation * ProtoLocs,SourceLocation EndProtoLoc,AttributeList * AttrList)900*67e74705SXin Li ActOnStartClassInterface(Scope *S, SourceLocation AtInterfaceLoc,
901*67e74705SXin Li                          IdentifierInfo *ClassName, SourceLocation ClassLoc,
902*67e74705SXin Li                          ObjCTypeParamList *typeParamList,
903*67e74705SXin Li                          IdentifierInfo *SuperName, SourceLocation SuperLoc,
904*67e74705SXin Li                          ArrayRef<ParsedType> SuperTypeArgs,
905*67e74705SXin Li                          SourceRange SuperTypeArgsRange,
906*67e74705SXin Li                          Decl * const *ProtoRefs, unsigned NumProtoRefs,
907*67e74705SXin Li                          const SourceLocation *ProtoLocs,
908*67e74705SXin Li                          SourceLocation EndProtoLoc, AttributeList *AttrList) {
909*67e74705SXin Li   assert(ClassName && "Missing class identifier");
910*67e74705SXin Li 
911*67e74705SXin Li   // Check for another declaration kind with the same name.
912*67e74705SXin Li   NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, ClassLoc,
913*67e74705SXin Li                                          LookupOrdinaryName, ForRedeclaration);
914*67e74705SXin Li 
915*67e74705SXin Li   if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
916*67e74705SXin Li     Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
917*67e74705SXin Li     Diag(PrevDecl->getLocation(), diag::note_previous_definition);
918*67e74705SXin Li   }
919*67e74705SXin Li 
920*67e74705SXin Li   // Create a declaration to describe this @interface.
921*67e74705SXin Li   ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
922*67e74705SXin Li 
923*67e74705SXin Li   if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) {
924*67e74705SXin Li     // A previous decl with a different name is because of
925*67e74705SXin Li     // @compatibility_alias, for example:
926*67e74705SXin Li     // \code
927*67e74705SXin Li     //   @class NewImage;
928*67e74705SXin Li     //   @compatibility_alias OldImage NewImage;
929*67e74705SXin Li     // \endcode
930*67e74705SXin Li     // A lookup for 'OldImage' will return the 'NewImage' decl.
931*67e74705SXin Li     //
932*67e74705SXin Li     // In such a case use the real declaration name, instead of the alias one,
933*67e74705SXin Li     // otherwise we will break IdentifierResolver and redecls-chain invariants.
934*67e74705SXin Li     // FIXME: If necessary, add a bit to indicate that this ObjCInterfaceDecl
935*67e74705SXin Li     // has been aliased.
936*67e74705SXin Li     ClassName = PrevIDecl->getIdentifier();
937*67e74705SXin Li   }
938*67e74705SXin Li 
939*67e74705SXin Li   // If there was a forward declaration with type parameters, check
940*67e74705SXin Li   // for consistency.
941*67e74705SXin Li   if (PrevIDecl) {
942*67e74705SXin Li     if (ObjCTypeParamList *prevTypeParamList = PrevIDecl->getTypeParamList()) {
943*67e74705SXin Li       if (typeParamList) {
944*67e74705SXin Li         // Both have type parameter lists; check for consistency.
945*67e74705SXin Li         if (checkTypeParamListConsistency(*this, prevTypeParamList,
946*67e74705SXin Li                                           typeParamList,
947*67e74705SXin Li                                           TypeParamListContext::Definition)) {
948*67e74705SXin Li           typeParamList = nullptr;
949*67e74705SXin Li         }
950*67e74705SXin Li       } else {
951*67e74705SXin Li         Diag(ClassLoc, diag::err_objc_parameterized_forward_class_first)
952*67e74705SXin Li           << ClassName;
953*67e74705SXin Li         Diag(prevTypeParamList->getLAngleLoc(), diag::note_previous_decl)
954*67e74705SXin Li           << ClassName;
955*67e74705SXin Li 
956*67e74705SXin Li         // Clone the type parameter list.
957*67e74705SXin Li         SmallVector<ObjCTypeParamDecl *, 4> clonedTypeParams;
958*67e74705SXin Li         for (auto typeParam : *prevTypeParamList) {
959*67e74705SXin Li           clonedTypeParams.push_back(
960*67e74705SXin Li             ObjCTypeParamDecl::Create(
961*67e74705SXin Li               Context,
962*67e74705SXin Li               CurContext,
963*67e74705SXin Li               typeParam->getVariance(),
964*67e74705SXin Li               SourceLocation(),
965*67e74705SXin Li               typeParam->getIndex(),
966*67e74705SXin Li               SourceLocation(),
967*67e74705SXin Li               typeParam->getIdentifier(),
968*67e74705SXin Li               SourceLocation(),
969*67e74705SXin Li               Context.getTrivialTypeSourceInfo(typeParam->getUnderlyingType())));
970*67e74705SXin Li         }
971*67e74705SXin Li 
972*67e74705SXin Li         typeParamList = ObjCTypeParamList::create(Context,
973*67e74705SXin Li                                                   SourceLocation(),
974*67e74705SXin Li                                                   clonedTypeParams,
975*67e74705SXin Li                                                   SourceLocation());
976*67e74705SXin Li       }
977*67e74705SXin Li     }
978*67e74705SXin Li   }
979*67e74705SXin Li 
980*67e74705SXin Li   ObjCInterfaceDecl *IDecl
981*67e74705SXin Li     = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName,
982*67e74705SXin Li                                 typeParamList, PrevIDecl, ClassLoc);
983*67e74705SXin Li   if (PrevIDecl) {
984*67e74705SXin Li     // Class already seen. Was it a definition?
985*67e74705SXin Li     if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) {
986*67e74705SXin Li       Diag(AtInterfaceLoc, diag::err_duplicate_class_def)
987*67e74705SXin Li         << PrevIDecl->getDeclName();
988*67e74705SXin Li       Diag(Def->getLocation(), diag::note_previous_definition);
989*67e74705SXin Li       IDecl->setInvalidDecl();
990*67e74705SXin Li     }
991*67e74705SXin Li   }
992*67e74705SXin Li 
993*67e74705SXin Li   if (AttrList)
994*67e74705SXin Li     ProcessDeclAttributeList(TUScope, IDecl, AttrList);
995*67e74705SXin Li   PushOnScopeChains(IDecl, TUScope);
996*67e74705SXin Li 
997*67e74705SXin Li   // Start the definition of this class. If we're in a redefinition case, there
998*67e74705SXin Li   // may already be a definition, so we'll end up adding to it.
999*67e74705SXin Li   if (!IDecl->hasDefinition())
1000*67e74705SXin Li     IDecl->startDefinition();
1001*67e74705SXin Li 
1002*67e74705SXin Li   if (SuperName) {
1003*67e74705SXin Li     // Diagnose availability in the context of the @interface.
1004*67e74705SXin Li     ContextRAII SavedContext(*this, IDecl);
1005*67e74705SXin Li 
1006*67e74705SXin Li     ActOnSuperClassOfClassInterface(S, AtInterfaceLoc, IDecl,
1007*67e74705SXin Li                                     ClassName, ClassLoc,
1008*67e74705SXin Li                                     SuperName, SuperLoc, SuperTypeArgs,
1009*67e74705SXin Li                                     SuperTypeArgsRange);
1010*67e74705SXin Li   } else { // we have a root class.
1011*67e74705SXin Li     IDecl->setEndOfDefinitionLoc(ClassLoc);
1012*67e74705SXin Li   }
1013*67e74705SXin Li 
1014*67e74705SXin Li   // Check then save referenced protocols.
1015*67e74705SXin Li   if (NumProtoRefs) {
1016*67e74705SXin Li     diagnoseUseOfProtocols(*this, IDecl, (ObjCProtocolDecl*const*)ProtoRefs,
1017*67e74705SXin Li                            NumProtoRefs, ProtoLocs);
1018*67e74705SXin Li     IDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs,
1019*67e74705SXin Li                            ProtoLocs, Context);
1020*67e74705SXin Li     IDecl->setEndOfDefinitionLoc(EndProtoLoc);
1021*67e74705SXin Li   }
1022*67e74705SXin Li 
1023*67e74705SXin Li   CheckObjCDeclScope(IDecl);
1024*67e74705SXin Li   return ActOnObjCContainerStartDefinition(IDecl);
1025*67e74705SXin Li }
1026*67e74705SXin Li 
1027*67e74705SXin Li /// ActOnTypedefedProtocols - this action finds protocol list as part of the
1028*67e74705SXin Li /// typedef'ed use for a qualified super class and adds them to the list
1029*67e74705SXin Li /// of the protocols.
ActOnTypedefedProtocols(SmallVectorImpl<Decl * > & ProtocolRefs,IdentifierInfo * SuperName,SourceLocation SuperLoc)1030*67e74705SXin Li void Sema::ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs,
1031*67e74705SXin Li                                    IdentifierInfo *SuperName,
1032*67e74705SXin Li                                    SourceLocation SuperLoc) {
1033*67e74705SXin Li   if (!SuperName)
1034*67e74705SXin Li     return;
1035*67e74705SXin Li   NamedDecl* IDecl = LookupSingleName(TUScope, SuperName, SuperLoc,
1036*67e74705SXin Li                                       LookupOrdinaryName);
1037*67e74705SXin Li   if (!IDecl)
1038*67e74705SXin Li     return;
1039*67e74705SXin Li 
1040*67e74705SXin Li   if (const TypedefNameDecl *TDecl = dyn_cast_or_null<TypedefNameDecl>(IDecl)) {
1041*67e74705SXin Li     QualType T = TDecl->getUnderlyingType();
1042*67e74705SXin Li     if (T->isObjCObjectType())
1043*67e74705SXin Li       if (const ObjCObjectType *OPT = T->getAs<ObjCObjectType>())
1044*67e74705SXin Li         ProtocolRefs.append(OPT->qual_begin(), OPT->qual_end());
1045*67e74705SXin Li   }
1046*67e74705SXin Li }
1047*67e74705SXin Li 
1048*67e74705SXin Li /// ActOnCompatibilityAlias - this action is called after complete parsing of
1049*67e74705SXin Li /// a \@compatibility_alias declaration. It sets up the alias relationships.
ActOnCompatibilityAlias(SourceLocation AtLoc,IdentifierInfo * AliasName,SourceLocation AliasLocation,IdentifierInfo * ClassName,SourceLocation ClassLocation)1050*67e74705SXin Li Decl *Sema::ActOnCompatibilityAlias(SourceLocation AtLoc,
1051*67e74705SXin Li                                     IdentifierInfo *AliasName,
1052*67e74705SXin Li                                     SourceLocation AliasLocation,
1053*67e74705SXin Li                                     IdentifierInfo *ClassName,
1054*67e74705SXin Li                                     SourceLocation ClassLocation) {
1055*67e74705SXin Li   // Look for previous declaration of alias name
1056*67e74705SXin Li   NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, AliasLocation,
1057*67e74705SXin Li                                       LookupOrdinaryName, ForRedeclaration);
1058*67e74705SXin Li   if (ADecl) {
1059*67e74705SXin Li     Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName;
1060*67e74705SXin Li     Diag(ADecl->getLocation(), diag::note_previous_declaration);
1061*67e74705SXin Li     return nullptr;
1062*67e74705SXin Li   }
1063*67e74705SXin Li   // Check for class declaration
1064*67e74705SXin Li   NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
1065*67e74705SXin Li                                        LookupOrdinaryName, ForRedeclaration);
1066*67e74705SXin Li   if (const TypedefNameDecl *TDecl =
1067*67e74705SXin Li         dyn_cast_or_null<TypedefNameDecl>(CDeclU)) {
1068*67e74705SXin Li     QualType T = TDecl->getUnderlyingType();
1069*67e74705SXin Li     if (T->isObjCObjectType()) {
1070*67e74705SXin Li       if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface()) {
1071*67e74705SXin Li         ClassName = IDecl->getIdentifier();
1072*67e74705SXin Li         CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
1073*67e74705SXin Li                                   LookupOrdinaryName, ForRedeclaration);
1074*67e74705SXin Li       }
1075*67e74705SXin Li     }
1076*67e74705SXin Li   }
1077*67e74705SXin Li   ObjCInterfaceDecl *CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDeclU);
1078*67e74705SXin Li   if (!CDecl) {
1079*67e74705SXin Li     Diag(ClassLocation, diag::warn_undef_interface) << ClassName;
1080*67e74705SXin Li     if (CDeclU)
1081*67e74705SXin Li       Diag(CDeclU->getLocation(), diag::note_previous_declaration);
1082*67e74705SXin Li     return nullptr;
1083*67e74705SXin Li   }
1084*67e74705SXin Li 
1085*67e74705SXin Li   // Everything checked out, instantiate a new alias declaration AST.
1086*67e74705SXin Li   ObjCCompatibleAliasDecl *AliasDecl =
1087*67e74705SXin Li     ObjCCompatibleAliasDecl::Create(Context, CurContext, AtLoc, AliasName, CDecl);
1088*67e74705SXin Li 
1089*67e74705SXin Li   if (!CheckObjCDeclScope(AliasDecl))
1090*67e74705SXin Li     PushOnScopeChains(AliasDecl, TUScope);
1091*67e74705SXin Li 
1092*67e74705SXin Li   return AliasDecl;
1093*67e74705SXin Li }
1094*67e74705SXin Li 
CheckForwardProtocolDeclarationForCircularDependency(IdentifierInfo * PName,SourceLocation & Ploc,SourceLocation PrevLoc,const ObjCList<ObjCProtocolDecl> & PList)1095*67e74705SXin Li bool Sema::CheckForwardProtocolDeclarationForCircularDependency(
1096*67e74705SXin Li   IdentifierInfo *PName,
1097*67e74705SXin Li   SourceLocation &Ploc, SourceLocation PrevLoc,
1098*67e74705SXin Li   const ObjCList<ObjCProtocolDecl> &PList) {
1099*67e74705SXin Li 
1100*67e74705SXin Li   bool res = false;
1101*67e74705SXin Li   for (ObjCList<ObjCProtocolDecl>::iterator I = PList.begin(),
1102*67e74705SXin Li        E = PList.end(); I != E; ++I) {
1103*67e74705SXin Li     if (ObjCProtocolDecl *PDecl = LookupProtocol((*I)->getIdentifier(),
1104*67e74705SXin Li                                                  Ploc)) {
1105*67e74705SXin Li       if (PDecl->getIdentifier() == PName) {
1106*67e74705SXin Li         Diag(Ploc, diag::err_protocol_has_circular_dependency);
1107*67e74705SXin Li         Diag(PrevLoc, diag::note_previous_definition);
1108*67e74705SXin Li         res = true;
1109*67e74705SXin Li       }
1110*67e74705SXin Li 
1111*67e74705SXin Li       if (!PDecl->hasDefinition())
1112*67e74705SXin Li         continue;
1113*67e74705SXin Li 
1114*67e74705SXin Li       if (CheckForwardProtocolDeclarationForCircularDependency(PName, Ploc,
1115*67e74705SXin Li             PDecl->getLocation(), PDecl->getReferencedProtocols()))
1116*67e74705SXin Li         res = true;
1117*67e74705SXin Li     }
1118*67e74705SXin Li   }
1119*67e74705SXin Li   return res;
1120*67e74705SXin Li }
1121*67e74705SXin Li 
1122*67e74705SXin Li Decl *
ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,IdentifierInfo * ProtocolName,SourceLocation ProtocolLoc,Decl * const * ProtoRefs,unsigned NumProtoRefs,const SourceLocation * ProtoLocs,SourceLocation EndProtoLoc,AttributeList * AttrList)1123*67e74705SXin Li Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
1124*67e74705SXin Li                                   IdentifierInfo *ProtocolName,
1125*67e74705SXin Li                                   SourceLocation ProtocolLoc,
1126*67e74705SXin Li                                   Decl * const *ProtoRefs,
1127*67e74705SXin Li                                   unsigned NumProtoRefs,
1128*67e74705SXin Li                                   const SourceLocation *ProtoLocs,
1129*67e74705SXin Li                                   SourceLocation EndProtoLoc,
1130*67e74705SXin Li                                   AttributeList *AttrList) {
1131*67e74705SXin Li   bool err = false;
1132*67e74705SXin Li   // FIXME: Deal with AttrList.
1133*67e74705SXin Li   assert(ProtocolName && "Missing protocol identifier");
1134*67e74705SXin Li   ObjCProtocolDecl *PrevDecl = LookupProtocol(ProtocolName, ProtocolLoc,
1135*67e74705SXin Li                                               ForRedeclaration);
1136*67e74705SXin Li   ObjCProtocolDecl *PDecl = nullptr;
1137*67e74705SXin Li   if (ObjCProtocolDecl *Def = PrevDecl? PrevDecl->getDefinition() : nullptr) {
1138*67e74705SXin Li     // If we already have a definition, complain.
1139*67e74705SXin Li     Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName;
1140*67e74705SXin Li     Diag(Def->getLocation(), diag::note_previous_definition);
1141*67e74705SXin Li 
1142*67e74705SXin Li     // Create a new protocol that is completely distinct from previous
1143*67e74705SXin Li     // declarations, and do not make this protocol available for name lookup.
1144*67e74705SXin Li     // That way, we'll end up completely ignoring the duplicate.
1145*67e74705SXin Li     // FIXME: Can we turn this into an error?
1146*67e74705SXin Li     PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName,
1147*67e74705SXin Li                                      ProtocolLoc, AtProtoInterfaceLoc,
1148*67e74705SXin Li                                      /*PrevDecl=*/nullptr);
1149*67e74705SXin Li     PDecl->startDefinition();
1150*67e74705SXin Li   } else {
1151*67e74705SXin Li     if (PrevDecl) {
1152*67e74705SXin Li       // Check for circular dependencies among protocol declarations. This can
1153*67e74705SXin Li       // only happen if this protocol was forward-declared.
1154*67e74705SXin Li       ObjCList<ObjCProtocolDecl> PList;
1155*67e74705SXin Li       PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context);
1156*67e74705SXin Li       err = CheckForwardProtocolDeclarationForCircularDependency(
1157*67e74705SXin Li               ProtocolName, ProtocolLoc, PrevDecl->getLocation(), PList);
1158*67e74705SXin Li     }
1159*67e74705SXin Li 
1160*67e74705SXin Li     // Create the new declaration.
1161*67e74705SXin Li     PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName,
1162*67e74705SXin Li                                      ProtocolLoc, AtProtoInterfaceLoc,
1163*67e74705SXin Li                                      /*PrevDecl=*/PrevDecl);
1164*67e74705SXin Li 
1165*67e74705SXin Li     PushOnScopeChains(PDecl, TUScope);
1166*67e74705SXin Li     PDecl->startDefinition();
1167*67e74705SXin Li   }
1168*67e74705SXin Li 
1169*67e74705SXin Li   if (AttrList)
1170*67e74705SXin Li     ProcessDeclAttributeList(TUScope, PDecl, AttrList);
1171*67e74705SXin Li 
1172*67e74705SXin Li   // Merge attributes from previous declarations.
1173*67e74705SXin Li   if (PrevDecl)
1174*67e74705SXin Li     mergeDeclAttributes(PDecl, PrevDecl);
1175*67e74705SXin Li 
1176*67e74705SXin Li   if (!err && NumProtoRefs ) {
1177*67e74705SXin Li     /// Check then save referenced protocols.
1178*67e74705SXin Li     diagnoseUseOfProtocols(*this, PDecl, (ObjCProtocolDecl*const*)ProtoRefs,
1179*67e74705SXin Li                            NumProtoRefs, ProtoLocs);
1180*67e74705SXin Li     PDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs,
1181*67e74705SXin Li                            ProtoLocs, Context);
1182*67e74705SXin Li   }
1183*67e74705SXin Li 
1184*67e74705SXin Li   CheckObjCDeclScope(PDecl);
1185*67e74705SXin Li   return ActOnObjCContainerStartDefinition(PDecl);
1186*67e74705SXin Li }
1187*67e74705SXin Li 
NestedProtocolHasNoDefinition(ObjCProtocolDecl * PDecl,ObjCProtocolDecl * & UndefinedProtocol)1188*67e74705SXin Li static bool NestedProtocolHasNoDefinition(ObjCProtocolDecl *PDecl,
1189*67e74705SXin Li                                           ObjCProtocolDecl *&UndefinedProtocol) {
1190*67e74705SXin Li   if (!PDecl->hasDefinition() || PDecl->getDefinition()->isHidden()) {
1191*67e74705SXin Li     UndefinedProtocol = PDecl;
1192*67e74705SXin Li     return true;
1193*67e74705SXin Li   }
1194*67e74705SXin Li 
1195*67e74705SXin Li   for (auto *PI : PDecl->protocols())
1196*67e74705SXin Li     if (NestedProtocolHasNoDefinition(PI, UndefinedProtocol)) {
1197*67e74705SXin Li       UndefinedProtocol = PI;
1198*67e74705SXin Li       return true;
1199*67e74705SXin Li     }
1200*67e74705SXin Li   return false;
1201*67e74705SXin Li }
1202*67e74705SXin Li 
1203*67e74705SXin Li /// FindProtocolDeclaration - This routine looks up protocols and
1204*67e74705SXin Li /// issues an error if they are not declared. It returns list of
1205*67e74705SXin Li /// protocol declarations in its 'Protocols' argument.
1206*67e74705SXin Li void
FindProtocolDeclaration(bool WarnOnDeclarations,bool ForObjCContainer,ArrayRef<IdentifierLocPair> ProtocolId,SmallVectorImpl<Decl * > & Protocols)1207*67e74705SXin Li Sema::FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer,
1208*67e74705SXin Li                               ArrayRef<IdentifierLocPair> ProtocolId,
1209*67e74705SXin Li                               SmallVectorImpl<Decl *> &Protocols) {
1210*67e74705SXin Li   for (const IdentifierLocPair &Pair : ProtocolId) {
1211*67e74705SXin Li     ObjCProtocolDecl *PDecl = LookupProtocol(Pair.first, Pair.second);
1212*67e74705SXin Li     if (!PDecl) {
1213*67e74705SXin Li       TypoCorrection Corrected = CorrectTypo(
1214*67e74705SXin Li           DeclarationNameInfo(Pair.first, Pair.second),
1215*67e74705SXin Li           LookupObjCProtocolName, TUScope, nullptr,
1216*67e74705SXin Li           llvm::make_unique<DeclFilterCCC<ObjCProtocolDecl>>(),
1217*67e74705SXin Li           CTK_ErrorRecovery);
1218*67e74705SXin Li       if ((PDecl = Corrected.getCorrectionDeclAs<ObjCProtocolDecl>()))
1219*67e74705SXin Li         diagnoseTypo(Corrected, PDiag(diag::err_undeclared_protocol_suggest)
1220*67e74705SXin Li                                     << Pair.first);
1221*67e74705SXin Li     }
1222*67e74705SXin Li 
1223*67e74705SXin Li     if (!PDecl) {
1224*67e74705SXin Li       Diag(Pair.second, diag::err_undeclared_protocol) << Pair.first;
1225*67e74705SXin Li       continue;
1226*67e74705SXin Li     }
1227*67e74705SXin Li     // If this is a forward protocol declaration, get its definition.
1228*67e74705SXin Li     if (!PDecl->isThisDeclarationADefinition() && PDecl->getDefinition())
1229*67e74705SXin Li       PDecl = PDecl->getDefinition();
1230*67e74705SXin Li 
1231*67e74705SXin Li     // For an objc container, delay protocol reference checking until after we
1232*67e74705SXin Li     // can set the objc decl as the availability context, otherwise check now.
1233*67e74705SXin Li     if (!ForObjCContainer) {
1234*67e74705SXin Li       (void)DiagnoseUseOfDecl(PDecl, Pair.second);
1235*67e74705SXin Li     }
1236*67e74705SXin Li 
1237*67e74705SXin Li     // If this is a forward declaration and we are supposed to warn in this
1238*67e74705SXin Li     // case, do it.
1239*67e74705SXin Li     // FIXME: Recover nicely in the hidden case.
1240*67e74705SXin Li     ObjCProtocolDecl *UndefinedProtocol;
1241*67e74705SXin Li 
1242*67e74705SXin Li     if (WarnOnDeclarations &&
1243*67e74705SXin Li         NestedProtocolHasNoDefinition(PDecl, UndefinedProtocol)) {
1244*67e74705SXin Li       Diag(Pair.second, diag::warn_undef_protocolref) << Pair.first;
1245*67e74705SXin Li       Diag(UndefinedProtocol->getLocation(), diag::note_protocol_decl_undefined)
1246*67e74705SXin Li         << UndefinedProtocol;
1247*67e74705SXin Li     }
1248*67e74705SXin Li     Protocols.push_back(PDecl);
1249*67e74705SXin Li   }
1250*67e74705SXin Li }
1251*67e74705SXin Li 
1252*67e74705SXin Li namespace {
1253*67e74705SXin Li // Callback to only accept typo corrections that are either
1254*67e74705SXin Li // Objective-C protocols or valid Objective-C type arguments.
1255*67e74705SXin Li class ObjCTypeArgOrProtocolValidatorCCC : public CorrectionCandidateCallback {
1256*67e74705SXin Li   ASTContext &Context;
1257*67e74705SXin Li   Sema::LookupNameKind LookupKind;
1258*67e74705SXin Li  public:
ObjCTypeArgOrProtocolValidatorCCC(ASTContext & context,Sema::LookupNameKind lookupKind)1259*67e74705SXin Li   ObjCTypeArgOrProtocolValidatorCCC(ASTContext &context,
1260*67e74705SXin Li                                     Sema::LookupNameKind lookupKind)
1261*67e74705SXin Li     : Context(context), LookupKind(lookupKind) { }
1262*67e74705SXin Li 
ValidateCandidate(const TypoCorrection & candidate)1263*67e74705SXin Li   bool ValidateCandidate(const TypoCorrection &candidate) override {
1264*67e74705SXin Li     // If we're allowed to find protocols and we have a protocol, accept it.
1265*67e74705SXin Li     if (LookupKind != Sema::LookupOrdinaryName) {
1266*67e74705SXin Li       if (candidate.getCorrectionDeclAs<ObjCProtocolDecl>())
1267*67e74705SXin Li         return true;
1268*67e74705SXin Li     }
1269*67e74705SXin Li 
1270*67e74705SXin Li     // If we're allowed to find type names and we have one, accept it.
1271*67e74705SXin Li     if (LookupKind != Sema::LookupObjCProtocolName) {
1272*67e74705SXin Li       // If we have a type declaration, we might accept this result.
1273*67e74705SXin Li       if (auto typeDecl = candidate.getCorrectionDeclAs<TypeDecl>()) {
1274*67e74705SXin Li         // If we found a tag declaration outside of C++, skip it. This
1275*67e74705SXin Li         // can happy because we look for any name when there is no
1276*67e74705SXin Li         // bias to protocol or type names.
1277*67e74705SXin Li         if (isa<RecordDecl>(typeDecl) && !Context.getLangOpts().CPlusPlus)
1278*67e74705SXin Li           return false;
1279*67e74705SXin Li 
1280*67e74705SXin Li         // Make sure the type is something we would accept as a type
1281*67e74705SXin Li         // argument.
1282*67e74705SXin Li         auto type = Context.getTypeDeclType(typeDecl);
1283*67e74705SXin Li         if (type->isObjCObjectPointerType() ||
1284*67e74705SXin Li             type->isBlockPointerType() ||
1285*67e74705SXin Li             type->isDependentType() ||
1286*67e74705SXin Li             type->isObjCObjectType())
1287*67e74705SXin Li           return true;
1288*67e74705SXin Li 
1289*67e74705SXin Li         return false;
1290*67e74705SXin Li       }
1291*67e74705SXin Li 
1292*67e74705SXin Li       // If we have an Objective-C class type, accept it; there will
1293*67e74705SXin Li       // be another fix to add the '*'.
1294*67e74705SXin Li       if (candidate.getCorrectionDeclAs<ObjCInterfaceDecl>())
1295*67e74705SXin Li         return true;
1296*67e74705SXin Li 
1297*67e74705SXin Li       return false;
1298*67e74705SXin Li     }
1299*67e74705SXin Li 
1300*67e74705SXin Li     return false;
1301*67e74705SXin Li   }
1302*67e74705SXin Li };
1303*67e74705SXin Li } // end anonymous namespace
1304*67e74705SXin Li 
DiagnoseTypeArgsAndProtocols(IdentifierInfo * ProtocolId,SourceLocation ProtocolLoc,IdentifierInfo * TypeArgId,SourceLocation TypeArgLoc,bool SelectProtocolFirst)1305*67e74705SXin Li void Sema::DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId,
1306*67e74705SXin Li                                         SourceLocation ProtocolLoc,
1307*67e74705SXin Li                                         IdentifierInfo *TypeArgId,
1308*67e74705SXin Li                                         SourceLocation TypeArgLoc,
1309*67e74705SXin Li                                         bool SelectProtocolFirst) {
1310*67e74705SXin Li   Diag(TypeArgLoc, diag::err_objc_type_args_and_protocols)
1311*67e74705SXin Li       << SelectProtocolFirst << TypeArgId << ProtocolId
1312*67e74705SXin Li       << SourceRange(ProtocolLoc);
1313*67e74705SXin Li }
1314*67e74705SXin Li 
actOnObjCTypeArgsOrProtocolQualifiers(Scope * S,ParsedType baseType,SourceLocation lAngleLoc,ArrayRef<IdentifierInfo * > identifiers,ArrayRef<SourceLocation> identifierLocs,SourceLocation rAngleLoc,SourceLocation & typeArgsLAngleLoc,SmallVectorImpl<ParsedType> & typeArgs,SourceLocation & typeArgsRAngleLoc,SourceLocation & protocolLAngleLoc,SmallVectorImpl<Decl * > & protocols,SourceLocation & protocolRAngleLoc,bool warnOnIncompleteProtocols)1315*67e74705SXin Li void Sema::actOnObjCTypeArgsOrProtocolQualifiers(
1316*67e74705SXin Li        Scope *S,
1317*67e74705SXin Li        ParsedType baseType,
1318*67e74705SXin Li        SourceLocation lAngleLoc,
1319*67e74705SXin Li        ArrayRef<IdentifierInfo *> identifiers,
1320*67e74705SXin Li        ArrayRef<SourceLocation> identifierLocs,
1321*67e74705SXin Li        SourceLocation rAngleLoc,
1322*67e74705SXin Li        SourceLocation &typeArgsLAngleLoc,
1323*67e74705SXin Li        SmallVectorImpl<ParsedType> &typeArgs,
1324*67e74705SXin Li        SourceLocation &typeArgsRAngleLoc,
1325*67e74705SXin Li        SourceLocation &protocolLAngleLoc,
1326*67e74705SXin Li        SmallVectorImpl<Decl *> &protocols,
1327*67e74705SXin Li        SourceLocation &protocolRAngleLoc,
1328*67e74705SXin Li        bool warnOnIncompleteProtocols) {
1329*67e74705SXin Li   // Local function that updates the declaration specifiers with
1330*67e74705SXin Li   // protocol information.
1331*67e74705SXin Li   unsigned numProtocolsResolved = 0;
1332*67e74705SXin Li   auto resolvedAsProtocols = [&] {
1333*67e74705SXin Li     assert(numProtocolsResolved == identifiers.size() && "Unresolved protocols");
1334*67e74705SXin Li 
1335*67e74705SXin Li     // Determine whether the base type is a parameterized class, in
1336*67e74705SXin Li     // which case we want to warn about typos such as
1337*67e74705SXin Li     // "NSArray<NSObject>" (that should be NSArray<NSObject *>).
1338*67e74705SXin Li     ObjCInterfaceDecl *baseClass = nullptr;
1339*67e74705SXin Li     QualType base = GetTypeFromParser(baseType, nullptr);
1340*67e74705SXin Li     bool allAreTypeNames = false;
1341*67e74705SXin Li     SourceLocation firstClassNameLoc;
1342*67e74705SXin Li     if (!base.isNull()) {
1343*67e74705SXin Li       if (const auto *objcObjectType = base->getAs<ObjCObjectType>()) {
1344*67e74705SXin Li         baseClass = objcObjectType->getInterface();
1345*67e74705SXin Li         if (baseClass) {
1346*67e74705SXin Li           if (auto typeParams = baseClass->getTypeParamList()) {
1347*67e74705SXin Li             if (typeParams->size() == numProtocolsResolved) {
1348*67e74705SXin Li               // Note that we should be looking for type names, too.
1349*67e74705SXin Li               allAreTypeNames = true;
1350*67e74705SXin Li             }
1351*67e74705SXin Li           }
1352*67e74705SXin Li         }
1353*67e74705SXin Li       }
1354*67e74705SXin Li     }
1355*67e74705SXin Li 
1356*67e74705SXin Li     for (unsigned i = 0, n = protocols.size(); i != n; ++i) {
1357*67e74705SXin Li       ObjCProtocolDecl *&proto
1358*67e74705SXin Li         = reinterpret_cast<ObjCProtocolDecl *&>(protocols[i]);
1359*67e74705SXin Li       // For an objc container, delay protocol reference checking until after we
1360*67e74705SXin Li       // can set the objc decl as the availability context, otherwise check now.
1361*67e74705SXin Li       if (!warnOnIncompleteProtocols) {
1362*67e74705SXin Li         (void)DiagnoseUseOfDecl(proto, identifierLocs[i]);
1363*67e74705SXin Li       }
1364*67e74705SXin Li 
1365*67e74705SXin Li       // If this is a forward protocol declaration, get its definition.
1366*67e74705SXin Li       if (!proto->isThisDeclarationADefinition() && proto->getDefinition())
1367*67e74705SXin Li         proto = proto->getDefinition();
1368*67e74705SXin Li 
1369*67e74705SXin Li       // If this is a forward declaration and we are supposed to warn in this
1370*67e74705SXin Li       // case, do it.
1371*67e74705SXin Li       // FIXME: Recover nicely in the hidden case.
1372*67e74705SXin Li       ObjCProtocolDecl *forwardDecl = nullptr;
1373*67e74705SXin Li       if (warnOnIncompleteProtocols &&
1374*67e74705SXin Li           NestedProtocolHasNoDefinition(proto, forwardDecl)) {
1375*67e74705SXin Li         Diag(identifierLocs[i], diag::warn_undef_protocolref)
1376*67e74705SXin Li           << proto->getDeclName();
1377*67e74705SXin Li         Diag(forwardDecl->getLocation(), diag::note_protocol_decl_undefined)
1378*67e74705SXin Li           << forwardDecl;
1379*67e74705SXin Li       }
1380*67e74705SXin Li 
1381*67e74705SXin Li       // If everything this far has been a type name (and we care
1382*67e74705SXin Li       // about such things), check whether this name refers to a type
1383*67e74705SXin Li       // as well.
1384*67e74705SXin Li       if (allAreTypeNames) {
1385*67e74705SXin Li         if (auto *decl = LookupSingleName(S, identifiers[i], identifierLocs[i],
1386*67e74705SXin Li                                           LookupOrdinaryName)) {
1387*67e74705SXin Li           if (isa<ObjCInterfaceDecl>(decl)) {
1388*67e74705SXin Li             if (firstClassNameLoc.isInvalid())
1389*67e74705SXin Li               firstClassNameLoc = identifierLocs[i];
1390*67e74705SXin Li           } else if (!isa<TypeDecl>(decl)) {
1391*67e74705SXin Li             // Not a type.
1392*67e74705SXin Li             allAreTypeNames = false;
1393*67e74705SXin Li           }
1394*67e74705SXin Li         } else {
1395*67e74705SXin Li           allAreTypeNames = false;
1396*67e74705SXin Li         }
1397*67e74705SXin Li       }
1398*67e74705SXin Li     }
1399*67e74705SXin Li 
1400*67e74705SXin Li     // All of the protocols listed also have type names, and at least
1401*67e74705SXin Li     // one is an Objective-C class name. Check whether all of the
1402*67e74705SXin Li     // protocol conformances are declared by the base class itself, in
1403*67e74705SXin Li     // which case we warn.
1404*67e74705SXin Li     if (allAreTypeNames && firstClassNameLoc.isValid()) {
1405*67e74705SXin Li       llvm::SmallPtrSet<ObjCProtocolDecl*, 8> knownProtocols;
1406*67e74705SXin Li       Context.CollectInheritedProtocols(baseClass, knownProtocols);
1407*67e74705SXin Li       bool allProtocolsDeclared = true;
1408*67e74705SXin Li       for (auto proto : protocols) {
1409*67e74705SXin Li         if (knownProtocols.count(static_cast<ObjCProtocolDecl *>(proto)) == 0) {
1410*67e74705SXin Li           allProtocolsDeclared = false;
1411*67e74705SXin Li           break;
1412*67e74705SXin Li         }
1413*67e74705SXin Li       }
1414*67e74705SXin Li 
1415*67e74705SXin Li       if (allProtocolsDeclared) {
1416*67e74705SXin Li         Diag(firstClassNameLoc, diag::warn_objc_redundant_qualified_class_type)
1417*67e74705SXin Li           << baseClass->getDeclName() << SourceRange(lAngleLoc, rAngleLoc)
1418*67e74705SXin Li           << FixItHint::CreateInsertion(getLocForEndOfToken(firstClassNameLoc),
1419*67e74705SXin Li                                         " *");
1420*67e74705SXin Li       }
1421*67e74705SXin Li     }
1422*67e74705SXin Li 
1423*67e74705SXin Li     protocolLAngleLoc = lAngleLoc;
1424*67e74705SXin Li     protocolRAngleLoc = rAngleLoc;
1425*67e74705SXin Li     assert(protocols.size() == identifierLocs.size());
1426*67e74705SXin Li   };
1427*67e74705SXin Li 
1428*67e74705SXin Li   // Attempt to resolve all of the identifiers as protocols.
1429*67e74705SXin Li   for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1430*67e74705SXin Li     ObjCProtocolDecl *proto = LookupProtocol(identifiers[i], identifierLocs[i]);
1431*67e74705SXin Li     protocols.push_back(proto);
1432*67e74705SXin Li     if (proto)
1433*67e74705SXin Li       ++numProtocolsResolved;
1434*67e74705SXin Li   }
1435*67e74705SXin Li 
1436*67e74705SXin Li   // If all of the names were protocols, these were protocol qualifiers.
1437*67e74705SXin Li   if (numProtocolsResolved == identifiers.size())
1438*67e74705SXin Li     return resolvedAsProtocols();
1439*67e74705SXin Li 
1440*67e74705SXin Li   // Attempt to resolve all of the identifiers as type names or
1441*67e74705SXin Li   // Objective-C class names. The latter is technically ill-formed,
1442*67e74705SXin Li   // but is probably something like \c NSArray<NSView *> missing the
1443*67e74705SXin Li   // \c*.
1444*67e74705SXin Li   typedef llvm::PointerUnion<TypeDecl *, ObjCInterfaceDecl *> TypeOrClassDecl;
1445*67e74705SXin Li   SmallVector<TypeOrClassDecl, 4> typeDecls;
1446*67e74705SXin Li   unsigned numTypeDeclsResolved = 0;
1447*67e74705SXin Li   for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1448*67e74705SXin Li     NamedDecl *decl = LookupSingleName(S, identifiers[i], identifierLocs[i],
1449*67e74705SXin Li                                        LookupOrdinaryName);
1450*67e74705SXin Li     if (!decl) {
1451*67e74705SXin Li       typeDecls.push_back(TypeOrClassDecl());
1452*67e74705SXin Li       continue;
1453*67e74705SXin Li     }
1454*67e74705SXin Li 
1455*67e74705SXin Li     if (auto typeDecl = dyn_cast<TypeDecl>(decl)) {
1456*67e74705SXin Li       typeDecls.push_back(typeDecl);
1457*67e74705SXin Li       ++numTypeDeclsResolved;
1458*67e74705SXin Li       continue;
1459*67e74705SXin Li     }
1460*67e74705SXin Li 
1461*67e74705SXin Li     if (auto objcClass = dyn_cast<ObjCInterfaceDecl>(decl)) {
1462*67e74705SXin Li       typeDecls.push_back(objcClass);
1463*67e74705SXin Li       ++numTypeDeclsResolved;
1464*67e74705SXin Li       continue;
1465*67e74705SXin Li     }
1466*67e74705SXin Li 
1467*67e74705SXin Li     typeDecls.push_back(TypeOrClassDecl());
1468*67e74705SXin Li   }
1469*67e74705SXin Li 
1470*67e74705SXin Li   AttributeFactory attrFactory;
1471*67e74705SXin Li 
1472*67e74705SXin Li   // Local function that forms a reference to the given type or
1473*67e74705SXin Li   // Objective-C class declaration.
1474*67e74705SXin Li   auto resolveTypeReference = [&](TypeOrClassDecl typeDecl, SourceLocation loc)
1475*67e74705SXin Li                                 -> TypeResult {
1476*67e74705SXin Li     // Form declaration specifiers. They simply refer to the type.
1477*67e74705SXin Li     DeclSpec DS(attrFactory);
1478*67e74705SXin Li     const char* prevSpec; // unused
1479*67e74705SXin Li     unsigned diagID; // unused
1480*67e74705SXin Li     QualType type;
1481*67e74705SXin Li     if (auto *actualTypeDecl = typeDecl.dyn_cast<TypeDecl *>())
1482*67e74705SXin Li       type = Context.getTypeDeclType(actualTypeDecl);
1483*67e74705SXin Li     else
1484*67e74705SXin Li       type = Context.getObjCInterfaceType(typeDecl.get<ObjCInterfaceDecl *>());
1485*67e74705SXin Li     TypeSourceInfo *parsedTSInfo = Context.getTrivialTypeSourceInfo(type, loc);
1486*67e74705SXin Li     ParsedType parsedType = CreateParsedType(type, parsedTSInfo);
1487*67e74705SXin Li     DS.SetTypeSpecType(DeclSpec::TST_typename, loc, prevSpec, diagID,
1488*67e74705SXin Li                        parsedType, Context.getPrintingPolicy());
1489*67e74705SXin Li     // Use the identifier location for the type source range.
1490*67e74705SXin Li     DS.SetRangeStart(loc);
1491*67e74705SXin Li     DS.SetRangeEnd(loc);
1492*67e74705SXin Li 
1493*67e74705SXin Li     // Form the declarator.
1494*67e74705SXin Li     Declarator D(DS, Declarator::TypeNameContext);
1495*67e74705SXin Li 
1496*67e74705SXin Li     // If we have a typedef of an Objective-C class type that is missing a '*',
1497*67e74705SXin Li     // add the '*'.
1498*67e74705SXin Li     if (type->getAs<ObjCInterfaceType>()) {
1499*67e74705SXin Li       SourceLocation starLoc = getLocForEndOfToken(loc);
1500*67e74705SXin Li       ParsedAttributes parsedAttrs(attrFactory);
1501*67e74705SXin Li       D.AddTypeInfo(DeclaratorChunk::getPointer(/*typeQuals=*/0, starLoc,
1502*67e74705SXin Li                                                 SourceLocation(),
1503*67e74705SXin Li                                                 SourceLocation(),
1504*67e74705SXin Li                                                 SourceLocation(),
1505*67e74705SXin Li                                                 SourceLocation(),
1506*67e74705SXin Li                                                 SourceLocation()),
1507*67e74705SXin Li                                                 parsedAttrs,
1508*67e74705SXin Li                                                 starLoc);
1509*67e74705SXin Li 
1510*67e74705SXin Li       // Diagnose the missing '*'.
1511*67e74705SXin Li       Diag(loc, diag::err_objc_type_arg_missing_star)
1512*67e74705SXin Li         << type
1513*67e74705SXin Li         << FixItHint::CreateInsertion(starLoc, " *");
1514*67e74705SXin Li     }
1515*67e74705SXin Li 
1516*67e74705SXin Li     // Convert this to a type.
1517*67e74705SXin Li     return ActOnTypeName(S, D);
1518*67e74705SXin Li   };
1519*67e74705SXin Li 
1520*67e74705SXin Li   // Local function that updates the declaration specifiers with
1521*67e74705SXin Li   // type argument information.
1522*67e74705SXin Li   auto resolvedAsTypeDecls = [&] {
1523*67e74705SXin Li     // We did not resolve these as protocols.
1524*67e74705SXin Li     protocols.clear();
1525*67e74705SXin Li 
1526*67e74705SXin Li     assert(numTypeDeclsResolved == identifiers.size() && "Unresolved type decl");
1527*67e74705SXin Li     // Map type declarations to type arguments.
1528*67e74705SXin Li     for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1529*67e74705SXin Li       // Map type reference to a type.
1530*67e74705SXin Li       TypeResult type = resolveTypeReference(typeDecls[i], identifierLocs[i]);
1531*67e74705SXin Li       if (!type.isUsable()) {
1532*67e74705SXin Li         typeArgs.clear();
1533*67e74705SXin Li         return;
1534*67e74705SXin Li       }
1535*67e74705SXin Li 
1536*67e74705SXin Li       typeArgs.push_back(type.get());
1537*67e74705SXin Li     }
1538*67e74705SXin Li 
1539*67e74705SXin Li     typeArgsLAngleLoc = lAngleLoc;
1540*67e74705SXin Li     typeArgsRAngleLoc = rAngleLoc;
1541*67e74705SXin Li   };
1542*67e74705SXin Li 
1543*67e74705SXin Li   // If all of the identifiers can be resolved as type names or
1544*67e74705SXin Li   // Objective-C class names, we have type arguments.
1545*67e74705SXin Li   if (numTypeDeclsResolved == identifiers.size())
1546*67e74705SXin Li     return resolvedAsTypeDecls();
1547*67e74705SXin Li 
1548*67e74705SXin Li   // Error recovery: some names weren't found, or we have a mix of
1549*67e74705SXin Li   // type and protocol names. Go resolve all of the unresolved names
1550*67e74705SXin Li   // and complain if we can't find a consistent answer.
1551*67e74705SXin Li   LookupNameKind lookupKind = LookupAnyName;
1552*67e74705SXin Li   for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1553*67e74705SXin Li     // If we already have a protocol or type. Check whether it is the
1554*67e74705SXin Li     // right thing.
1555*67e74705SXin Li     if (protocols[i] || typeDecls[i]) {
1556*67e74705SXin Li       // If we haven't figured out whether we want types or protocols
1557*67e74705SXin Li       // yet, try to figure it out from this name.
1558*67e74705SXin Li       if (lookupKind == LookupAnyName) {
1559*67e74705SXin Li         // If this name refers to both a protocol and a type (e.g., \c
1560*67e74705SXin Li         // NSObject), don't conclude anything yet.
1561*67e74705SXin Li         if (protocols[i] && typeDecls[i])
1562*67e74705SXin Li           continue;
1563*67e74705SXin Li 
1564*67e74705SXin Li         // Otherwise, let this name decide whether we'll be correcting
1565*67e74705SXin Li         // toward types or protocols.
1566*67e74705SXin Li         lookupKind = protocols[i] ? LookupObjCProtocolName
1567*67e74705SXin Li                                   : LookupOrdinaryName;
1568*67e74705SXin Li         continue;
1569*67e74705SXin Li       }
1570*67e74705SXin Li 
1571*67e74705SXin Li       // If we want protocols and we have a protocol, there's nothing
1572*67e74705SXin Li       // more to do.
1573*67e74705SXin Li       if (lookupKind == LookupObjCProtocolName && protocols[i])
1574*67e74705SXin Li         continue;
1575*67e74705SXin Li 
1576*67e74705SXin Li       // If we want types and we have a type declaration, there's
1577*67e74705SXin Li       // nothing more to do.
1578*67e74705SXin Li       if (lookupKind == LookupOrdinaryName && typeDecls[i])
1579*67e74705SXin Li         continue;
1580*67e74705SXin Li 
1581*67e74705SXin Li       // We have a conflict: some names refer to protocols and others
1582*67e74705SXin Li       // refer to types.
1583*67e74705SXin Li       DiagnoseTypeArgsAndProtocols(identifiers[0], identifierLocs[0],
1584*67e74705SXin Li                                    identifiers[i], identifierLocs[i],
1585*67e74705SXin Li                                    protocols[i] != nullptr);
1586*67e74705SXin Li 
1587*67e74705SXin Li       protocols.clear();
1588*67e74705SXin Li       typeArgs.clear();
1589*67e74705SXin Li       return;
1590*67e74705SXin Li     }
1591*67e74705SXin Li 
1592*67e74705SXin Li     // Perform typo correction on the name.
1593*67e74705SXin Li     TypoCorrection corrected = CorrectTypo(
1594*67e74705SXin Li         DeclarationNameInfo(identifiers[i], identifierLocs[i]), lookupKind, S,
1595*67e74705SXin Li         nullptr,
1596*67e74705SXin Li         llvm::make_unique<ObjCTypeArgOrProtocolValidatorCCC>(Context,
1597*67e74705SXin Li                                                              lookupKind),
1598*67e74705SXin Li         CTK_ErrorRecovery);
1599*67e74705SXin Li     if (corrected) {
1600*67e74705SXin Li       // Did we find a protocol?
1601*67e74705SXin Li       if (auto proto = corrected.getCorrectionDeclAs<ObjCProtocolDecl>()) {
1602*67e74705SXin Li         diagnoseTypo(corrected,
1603*67e74705SXin Li                      PDiag(diag::err_undeclared_protocol_suggest)
1604*67e74705SXin Li                        << identifiers[i]);
1605*67e74705SXin Li         lookupKind = LookupObjCProtocolName;
1606*67e74705SXin Li         protocols[i] = proto;
1607*67e74705SXin Li         ++numProtocolsResolved;
1608*67e74705SXin Li         continue;
1609*67e74705SXin Li       }
1610*67e74705SXin Li 
1611*67e74705SXin Li       // Did we find a type?
1612*67e74705SXin Li       if (auto typeDecl = corrected.getCorrectionDeclAs<TypeDecl>()) {
1613*67e74705SXin Li         diagnoseTypo(corrected,
1614*67e74705SXin Li                      PDiag(diag::err_unknown_typename_suggest)
1615*67e74705SXin Li                        << identifiers[i]);
1616*67e74705SXin Li         lookupKind = LookupOrdinaryName;
1617*67e74705SXin Li         typeDecls[i] = typeDecl;
1618*67e74705SXin Li         ++numTypeDeclsResolved;
1619*67e74705SXin Li         continue;
1620*67e74705SXin Li       }
1621*67e74705SXin Li 
1622*67e74705SXin Li       // Did we find an Objective-C class?
1623*67e74705SXin Li       if (auto objcClass = corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) {
1624*67e74705SXin Li         diagnoseTypo(corrected,
1625*67e74705SXin Li                      PDiag(diag::err_unknown_type_or_class_name_suggest)
1626*67e74705SXin Li                        << identifiers[i] << true);
1627*67e74705SXin Li         lookupKind = LookupOrdinaryName;
1628*67e74705SXin Li         typeDecls[i] = objcClass;
1629*67e74705SXin Li         ++numTypeDeclsResolved;
1630*67e74705SXin Li         continue;
1631*67e74705SXin Li       }
1632*67e74705SXin Li     }
1633*67e74705SXin Li 
1634*67e74705SXin Li     // We couldn't find anything.
1635*67e74705SXin Li     Diag(identifierLocs[i],
1636*67e74705SXin Li          (lookupKind == LookupAnyName ? diag::err_objc_type_arg_missing
1637*67e74705SXin Li           : lookupKind == LookupObjCProtocolName ? diag::err_undeclared_protocol
1638*67e74705SXin Li           : diag::err_unknown_typename))
1639*67e74705SXin Li       << identifiers[i];
1640*67e74705SXin Li     protocols.clear();
1641*67e74705SXin Li     typeArgs.clear();
1642*67e74705SXin Li     return;
1643*67e74705SXin Li   }
1644*67e74705SXin Li 
1645*67e74705SXin Li   // If all of the names were (corrected to) protocols, these were
1646*67e74705SXin Li   // protocol qualifiers.
1647*67e74705SXin Li   if (numProtocolsResolved == identifiers.size())
1648*67e74705SXin Li     return resolvedAsProtocols();
1649*67e74705SXin Li 
1650*67e74705SXin Li   // Otherwise, all of the names were (corrected to) types.
1651*67e74705SXin Li   assert(numTypeDeclsResolved == identifiers.size() && "Not all types?");
1652*67e74705SXin Li   return resolvedAsTypeDecls();
1653*67e74705SXin Li }
1654*67e74705SXin Li 
1655*67e74705SXin Li /// DiagnoseClassExtensionDupMethods - Check for duplicate declaration of
1656*67e74705SXin Li /// a class method in its extension.
1657*67e74705SXin Li ///
DiagnoseClassExtensionDupMethods(ObjCCategoryDecl * CAT,ObjCInterfaceDecl * ID)1658*67e74705SXin Li void Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
1659*67e74705SXin Li                                             ObjCInterfaceDecl *ID) {
1660*67e74705SXin Li   if (!ID)
1661*67e74705SXin Li     return;  // Possibly due to previous error
1662*67e74705SXin Li 
1663*67e74705SXin Li   llvm::DenseMap<Selector, const ObjCMethodDecl*> MethodMap;
1664*67e74705SXin Li   for (auto *MD : ID->methods())
1665*67e74705SXin Li     MethodMap[MD->getSelector()] = MD;
1666*67e74705SXin Li 
1667*67e74705SXin Li   if (MethodMap.empty())
1668*67e74705SXin Li     return;
1669*67e74705SXin Li   for (const auto *Method : CAT->methods()) {
1670*67e74705SXin Li     const ObjCMethodDecl *&PrevMethod = MethodMap[Method->getSelector()];
1671*67e74705SXin Li     if (PrevMethod &&
1672*67e74705SXin Li         (PrevMethod->isInstanceMethod() == Method->isInstanceMethod()) &&
1673*67e74705SXin Li         !MatchTwoMethodDeclarations(Method, PrevMethod)) {
1674*67e74705SXin Li       Diag(Method->getLocation(), diag::err_duplicate_method_decl)
1675*67e74705SXin Li             << Method->getDeclName();
1676*67e74705SXin Li       Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
1677*67e74705SXin Li     }
1678*67e74705SXin Li   }
1679*67e74705SXin Li }
1680*67e74705SXin Li 
1681*67e74705SXin Li /// ActOnForwardProtocolDeclaration - Handle \@protocol foo;
1682*67e74705SXin Li Sema::DeclGroupPtrTy
ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,ArrayRef<IdentifierLocPair> IdentList,AttributeList * attrList)1683*67e74705SXin Li Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
1684*67e74705SXin Li                                       ArrayRef<IdentifierLocPair> IdentList,
1685*67e74705SXin Li                                       AttributeList *attrList) {
1686*67e74705SXin Li   SmallVector<Decl *, 8> DeclsInGroup;
1687*67e74705SXin Li   for (const IdentifierLocPair &IdentPair : IdentList) {
1688*67e74705SXin Li     IdentifierInfo *Ident = IdentPair.first;
1689*67e74705SXin Li     ObjCProtocolDecl *PrevDecl = LookupProtocol(Ident, IdentPair.second,
1690*67e74705SXin Li                                                 ForRedeclaration);
1691*67e74705SXin Li     ObjCProtocolDecl *PDecl
1692*67e74705SXin Li       = ObjCProtocolDecl::Create(Context, CurContext, Ident,
1693*67e74705SXin Li                                  IdentPair.second, AtProtocolLoc,
1694*67e74705SXin Li                                  PrevDecl);
1695*67e74705SXin Li 
1696*67e74705SXin Li     PushOnScopeChains(PDecl, TUScope);
1697*67e74705SXin Li     CheckObjCDeclScope(PDecl);
1698*67e74705SXin Li 
1699*67e74705SXin Li     if (attrList)
1700*67e74705SXin Li       ProcessDeclAttributeList(TUScope, PDecl, attrList);
1701*67e74705SXin Li 
1702*67e74705SXin Li     if (PrevDecl)
1703*67e74705SXin Li       mergeDeclAttributes(PDecl, PrevDecl);
1704*67e74705SXin Li 
1705*67e74705SXin Li     DeclsInGroup.push_back(PDecl);
1706*67e74705SXin Li   }
1707*67e74705SXin Li 
1708*67e74705SXin Li   return BuildDeclaratorGroup(DeclsInGroup, false);
1709*67e74705SXin Li }
1710*67e74705SXin Li 
1711*67e74705SXin Li Decl *Sema::
ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,IdentifierInfo * ClassName,SourceLocation ClassLoc,ObjCTypeParamList * typeParamList,IdentifierInfo * CategoryName,SourceLocation CategoryLoc,Decl * const * ProtoRefs,unsigned NumProtoRefs,const SourceLocation * ProtoLocs,SourceLocation EndProtoLoc)1712*67e74705SXin Li ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
1713*67e74705SXin Li                             IdentifierInfo *ClassName, SourceLocation ClassLoc,
1714*67e74705SXin Li                             ObjCTypeParamList *typeParamList,
1715*67e74705SXin Li                             IdentifierInfo *CategoryName,
1716*67e74705SXin Li                             SourceLocation CategoryLoc,
1717*67e74705SXin Li                             Decl * const *ProtoRefs,
1718*67e74705SXin Li                             unsigned NumProtoRefs,
1719*67e74705SXin Li                             const SourceLocation *ProtoLocs,
1720*67e74705SXin Li                             SourceLocation EndProtoLoc) {
1721*67e74705SXin Li   ObjCCategoryDecl *CDecl;
1722*67e74705SXin Li   ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true);
1723*67e74705SXin Li 
1724*67e74705SXin Li   /// Check that class of this category is already completely declared.
1725*67e74705SXin Li 
1726*67e74705SXin Li   if (!IDecl
1727*67e74705SXin Li       || RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
1728*67e74705SXin Li                              diag::err_category_forward_interface,
1729*67e74705SXin Li                              CategoryName == nullptr)) {
1730*67e74705SXin Li     // Create an invalid ObjCCategoryDecl to serve as context for
1731*67e74705SXin Li     // the enclosing method declarations.  We mark the decl invalid
1732*67e74705SXin Li     // to make it clear that this isn't a valid AST.
1733*67e74705SXin Li     CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc,
1734*67e74705SXin Li                                      ClassLoc, CategoryLoc, CategoryName,
1735*67e74705SXin Li                                      IDecl, typeParamList);
1736*67e74705SXin Li     CDecl->setInvalidDecl();
1737*67e74705SXin Li     CurContext->addDecl(CDecl);
1738*67e74705SXin Li 
1739*67e74705SXin Li     if (!IDecl)
1740*67e74705SXin Li       Diag(ClassLoc, diag::err_undef_interface) << ClassName;
1741*67e74705SXin Li     return ActOnObjCContainerStartDefinition(CDecl);
1742*67e74705SXin Li   }
1743*67e74705SXin Li 
1744*67e74705SXin Li   if (!CategoryName && IDecl->getImplementation()) {
1745*67e74705SXin Li     Diag(ClassLoc, diag::err_class_extension_after_impl) << ClassName;
1746*67e74705SXin Li     Diag(IDecl->getImplementation()->getLocation(),
1747*67e74705SXin Li           diag::note_implementation_declared);
1748*67e74705SXin Li   }
1749*67e74705SXin Li 
1750*67e74705SXin Li   if (CategoryName) {
1751*67e74705SXin Li     /// Check for duplicate interface declaration for this category
1752*67e74705SXin Li     if (ObjCCategoryDecl *Previous
1753*67e74705SXin Li           = IDecl->FindCategoryDeclaration(CategoryName)) {
1754*67e74705SXin Li       // Class extensions can be declared multiple times, categories cannot.
1755*67e74705SXin Li       Diag(CategoryLoc, diag::warn_dup_category_def)
1756*67e74705SXin Li         << ClassName << CategoryName;
1757*67e74705SXin Li       Diag(Previous->getLocation(), diag::note_previous_definition);
1758*67e74705SXin Li     }
1759*67e74705SXin Li   }
1760*67e74705SXin Li 
1761*67e74705SXin Li   // If we have a type parameter list, check it.
1762*67e74705SXin Li   if (typeParamList) {
1763*67e74705SXin Li     if (auto prevTypeParamList = IDecl->getTypeParamList()) {
1764*67e74705SXin Li       if (checkTypeParamListConsistency(*this, prevTypeParamList, typeParamList,
1765*67e74705SXin Li                                         CategoryName
1766*67e74705SXin Li                                           ? TypeParamListContext::Category
1767*67e74705SXin Li                                           : TypeParamListContext::Extension))
1768*67e74705SXin Li         typeParamList = nullptr;
1769*67e74705SXin Li     } else {
1770*67e74705SXin Li       Diag(typeParamList->getLAngleLoc(),
1771*67e74705SXin Li            diag::err_objc_parameterized_category_nonclass)
1772*67e74705SXin Li         << (CategoryName != nullptr)
1773*67e74705SXin Li         << ClassName
1774*67e74705SXin Li         << typeParamList->getSourceRange();
1775*67e74705SXin Li 
1776*67e74705SXin Li       typeParamList = nullptr;
1777*67e74705SXin Li     }
1778*67e74705SXin Li   }
1779*67e74705SXin Li 
1780*67e74705SXin Li   CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc,
1781*67e74705SXin Li                                    ClassLoc, CategoryLoc, CategoryName, IDecl,
1782*67e74705SXin Li                                    typeParamList);
1783*67e74705SXin Li   // FIXME: PushOnScopeChains?
1784*67e74705SXin Li   CurContext->addDecl(CDecl);
1785*67e74705SXin Li 
1786*67e74705SXin Li   if (NumProtoRefs) {
1787*67e74705SXin Li     diagnoseUseOfProtocols(*this, CDecl, (ObjCProtocolDecl*const*)ProtoRefs,
1788*67e74705SXin Li                            NumProtoRefs, ProtoLocs);
1789*67e74705SXin Li     CDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs,
1790*67e74705SXin Li                            ProtoLocs, Context);
1791*67e74705SXin Li     // Protocols in the class extension belong to the class.
1792*67e74705SXin Li     if (CDecl->IsClassExtension())
1793*67e74705SXin Li      IDecl->mergeClassExtensionProtocolList((ObjCProtocolDecl*const*)ProtoRefs,
1794*67e74705SXin Li                                             NumProtoRefs, Context);
1795*67e74705SXin Li   }
1796*67e74705SXin Li 
1797*67e74705SXin Li   CheckObjCDeclScope(CDecl);
1798*67e74705SXin Li   return ActOnObjCContainerStartDefinition(CDecl);
1799*67e74705SXin Li }
1800*67e74705SXin Li 
1801*67e74705SXin Li /// ActOnStartCategoryImplementation - Perform semantic checks on the
1802*67e74705SXin Li /// category implementation declaration and build an ObjCCategoryImplDecl
1803*67e74705SXin Li /// object.
ActOnStartCategoryImplementation(SourceLocation AtCatImplLoc,IdentifierInfo * ClassName,SourceLocation ClassLoc,IdentifierInfo * CatName,SourceLocation CatLoc)1804*67e74705SXin Li Decl *Sema::ActOnStartCategoryImplementation(
1805*67e74705SXin Li                       SourceLocation AtCatImplLoc,
1806*67e74705SXin Li                       IdentifierInfo *ClassName, SourceLocation ClassLoc,
1807*67e74705SXin Li                       IdentifierInfo *CatName, SourceLocation CatLoc) {
1808*67e74705SXin Li   ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true);
1809*67e74705SXin Li   ObjCCategoryDecl *CatIDecl = nullptr;
1810*67e74705SXin Li   if (IDecl && IDecl->hasDefinition()) {
1811*67e74705SXin Li     CatIDecl = IDecl->FindCategoryDeclaration(CatName);
1812*67e74705SXin Li     if (!CatIDecl) {
1813*67e74705SXin Li       // Category @implementation with no corresponding @interface.
1814*67e74705SXin Li       // Create and install one.
1815*67e74705SXin Li       CatIDecl = ObjCCategoryDecl::Create(Context, CurContext, AtCatImplLoc,
1816*67e74705SXin Li                                           ClassLoc, CatLoc,
1817*67e74705SXin Li                                           CatName, IDecl,
1818*67e74705SXin Li                                           /*typeParamList=*/nullptr);
1819*67e74705SXin Li       CatIDecl->setImplicit();
1820*67e74705SXin Li     }
1821*67e74705SXin Li   }
1822*67e74705SXin Li 
1823*67e74705SXin Li   ObjCCategoryImplDecl *CDecl =
1824*67e74705SXin Li     ObjCCategoryImplDecl::Create(Context, CurContext, CatName, IDecl,
1825*67e74705SXin Li                                  ClassLoc, AtCatImplLoc, CatLoc);
1826*67e74705SXin Li   /// Check that class of this category is already completely declared.
1827*67e74705SXin Li   if (!IDecl) {
1828*67e74705SXin Li     Diag(ClassLoc, diag::err_undef_interface) << ClassName;
1829*67e74705SXin Li     CDecl->setInvalidDecl();
1830*67e74705SXin Li   } else if (RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
1831*67e74705SXin Li                                  diag::err_undef_interface)) {
1832*67e74705SXin Li     CDecl->setInvalidDecl();
1833*67e74705SXin Li   }
1834*67e74705SXin Li 
1835*67e74705SXin Li   // FIXME: PushOnScopeChains?
1836*67e74705SXin Li   CurContext->addDecl(CDecl);
1837*67e74705SXin Li 
1838*67e74705SXin Li   // If the interface is deprecated/unavailable, warn/error about it.
1839*67e74705SXin Li   if (IDecl)
1840*67e74705SXin Li     DiagnoseUseOfDecl(IDecl, ClassLoc);
1841*67e74705SXin Li 
1842*67e74705SXin Li   // If the interface has the objc_runtime_visible attribute, we
1843*67e74705SXin Li   // cannot implement a category for it.
1844*67e74705SXin Li   if (IDecl && IDecl->hasAttr<ObjCRuntimeVisibleAttr>()) {
1845*67e74705SXin Li     Diag(ClassLoc, diag::err_objc_runtime_visible_category)
1846*67e74705SXin Li       << IDecl->getDeclName();
1847*67e74705SXin Li   }
1848*67e74705SXin Li 
1849*67e74705SXin Li   /// Check that CatName, category name, is not used in another implementation.
1850*67e74705SXin Li   if (CatIDecl) {
1851*67e74705SXin Li     if (CatIDecl->getImplementation()) {
1852*67e74705SXin Li       Diag(ClassLoc, diag::err_dup_implementation_category) << ClassName
1853*67e74705SXin Li         << CatName;
1854*67e74705SXin Li       Diag(CatIDecl->getImplementation()->getLocation(),
1855*67e74705SXin Li            diag::note_previous_definition);
1856*67e74705SXin Li       CDecl->setInvalidDecl();
1857*67e74705SXin Li     } else {
1858*67e74705SXin Li       CatIDecl->setImplementation(CDecl);
1859*67e74705SXin Li       // Warn on implementating category of deprecated class under
1860*67e74705SXin Li       // -Wdeprecated-implementations flag.
1861*67e74705SXin Li       DiagnoseObjCImplementedDeprecations(*this,
1862*67e74705SXin Li                                           dyn_cast<NamedDecl>(IDecl),
1863*67e74705SXin Li                                           CDecl->getLocation(), 2);
1864*67e74705SXin Li     }
1865*67e74705SXin Li   }
1866*67e74705SXin Li 
1867*67e74705SXin Li   CheckObjCDeclScope(CDecl);
1868*67e74705SXin Li   return ActOnObjCContainerStartDefinition(CDecl);
1869*67e74705SXin Li }
1870*67e74705SXin Li 
ActOnStartClassImplementation(SourceLocation AtClassImplLoc,IdentifierInfo * ClassName,SourceLocation ClassLoc,IdentifierInfo * SuperClassname,SourceLocation SuperClassLoc)1871*67e74705SXin Li Decl *Sema::ActOnStartClassImplementation(
1872*67e74705SXin Li                       SourceLocation AtClassImplLoc,
1873*67e74705SXin Li                       IdentifierInfo *ClassName, SourceLocation ClassLoc,
1874*67e74705SXin Li                       IdentifierInfo *SuperClassname,
1875*67e74705SXin Li                       SourceLocation SuperClassLoc) {
1876*67e74705SXin Li   ObjCInterfaceDecl *IDecl = nullptr;
1877*67e74705SXin Li   // Check for another declaration kind with the same name.
1878*67e74705SXin Li   NamedDecl *PrevDecl
1879*67e74705SXin Li     = LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName,
1880*67e74705SXin Li                        ForRedeclaration);
1881*67e74705SXin Li   if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
1882*67e74705SXin Li     Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
1883*67e74705SXin Li     Diag(PrevDecl->getLocation(), diag::note_previous_definition);
1884*67e74705SXin Li   } else if ((IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))) {
1885*67e74705SXin Li     // FIXME: This will produce an error if the definition of the interface has
1886*67e74705SXin Li     // been imported from a module but is not visible.
1887*67e74705SXin Li     RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
1888*67e74705SXin Li                         diag::warn_undef_interface);
1889*67e74705SXin Li   } else {
1890*67e74705SXin Li     // We did not find anything with the name ClassName; try to correct for
1891*67e74705SXin Li     // typos in the class name.
1892*67e74705SXin Li     TypoCorrection Corrected = CorrectTypo(
1893*67e74705SXin Li         DeclarationNameInfo(ClassName, ClassLoc), LookupOrdinaryName, TUScope,
1894*67e74705SXin Li         nullptr, llvm::make_unique<ObjCInterfaceValidatorCCC>(), CTK_NonError);
1895*67e74705SXin Li     if (Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) {
1896*67e74705SXin Li       // Suggest the (potentially) correct interface name. Don't provide a
1897*67e74705SXin Li       // code-modification hint or use the typo name for recovery, because
1898*67e74705SXin Li       // this is just a warning. The program may actually be correct.
1899*67e74705SXin Li       diagnoseTypo(Corrected,
1900*67e74705SXin Li                    PDiag(diag::warn_undef_interface_suggest) << ClassName,
1901*67e74705SXin Li                    /*ErrorRecovery*/false);
1902*67e74705SXin Li     } else {
1903*67e74705SXin Li       Diag(ClassLoc, diag::warn_undef_interface) << ClassName;
1904*67e74705SXin Li     }
1905*67e74705SXin Li   }
1906*67e74705SXin Li 
1907*67e74705SXin Li   // Check that super class name is valid class name
1908*67e74705SXin Li   ObjCInterfaceDecl *SDecl = nullptr;
1909*67e74705SXin Li   if (SuperClassname) {
1910*67e74705SXin Li     // Check if a different kind of symbol declared in this scope.
1911*67e74705SXin Li     PrevDecl = LookupSingleName(TUScope, SuperClassname, SuperClassLoc,
1912*67e74705SXin Li                                 LookupOrdinaryName);
1913*67e74705SXin Li     if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
1914*67e74705SXin Li       Diag(SuperClassLoc, diag::err_redefinition_different_kind)
1915*67e74705SXin Li         << SuperClassname;
1916*67e74705SXin Li       Diag(PrevDecl->getLocation(), diag::note_previous_definition);
1917*67e74705SXin Li     } else {
1918*67e74705SXin Li       SDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
1919*67e74705SXin Li       if (SDecl && !SDecl->hasDefinition())
1920*67e74705SXin Li         SDecl = nullptr;
1921*67e74705SXin Li       if (!SDecl)
1922*67e74705SXin Li         Diag(SuperClassLoc, diag::err_undef_superclass)
1923*67e74705SXin Li           << SuperClassname << ClassName;
1924*67e74705SXin Li       else if (IDecl && !declaresSameEntity(IDecl->getSuperClass(), SDecl)) {
1925*67e74705SXin Li         // This implementation and its interface do not have the same
1926*67e74705SXin Li         // super class.
1927*67e74705SXin Li         Diag(SuperClassLoc, diag::err_conflicting_super_class)
1928*67e74705SXin Li           << SDecl->getDeclName();
1929*67e74705SXin Li         Diag(SDecl->getLocation(), diag::note_previous_definition);
1930*67e74705SXin Li       }
1931*67e74705SXin Li     }
1932*67e74705SXin Li   }
1933*67e74705SXin Li 
1934*67e74705SXin Li   if (!IDecl) {
1935*67e74705SXin Li     // Legacy case of @implementation with no corresponding @interface.
1936*67e74705SXin Li     // Build, chain & install the interface decl into the identifier.
1937*67e74705SXin Li 
1938*67e74705SXin Li     // FIXME: Do we support attributes on the @implementation? If so we should
1939*67e74705SXin Li     // copy them over.
1940*67e74705SXin Li     IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
1941*67e74705SXin Li                                       ClassName, /*typeParamList=*/nullptr,
1942*67e74705SXin Li                                       /*PrevDecl=*/nullptr, ClassLoc,
1943*67e74705SXin Li                                       true);
1944*67e74705SXin Li     IDecl->startDefinition();
1945*67e74705SXin Li     if (SDecl) {
1946*67e74705SXin Li       IDecl->setSuperClass(Context.getTrivialTypeSourceInfo(
1947*67e74705SXin Li                              Context.getObjCInterfaceType(SDecl),
1948*67e74705SXin Li                              SuperClassLoc));
1949*67e74705SXin Li       IDecl->setEndOfDefinitionLoc(SuperClassLoc);
1950*67e74705SXin Li     } else {
1951*67e74705SXin Li       IDecl->setEndOfDefinitionLoc(ClassLoc);
1952*67e74705SXin Li     }
1953*67e74705SXin Li 
1954*67e74705SXin Li     PushOnScopeChains(IDecl, TUScope);
1955*67e74705SXin Li   } else {
1956*67e74705SXin Li     // Mark the interface as being completed, even if it was just as
1957*67e74705SXin Li     //   @class ....;
1958*67e74705SXin Li     // declaration; the user cannot reopen it.
1959*67e74705SXin Li     if (!IDecl->hasDefinition())
1960*67e74705SXin Li       IDecl->startDefinition();
1961*67e74705SXin Li   }
1962*67e74705SXin Li 
1963*67e74705SXin Li   ObjCImplementationDecl* IMPDecl =
1964*67e74705SXin Li     ObjCImplementationDecl::Create(Context, CurContext, IDecl, SDecl,
1965*67e74705SXin Li                                    ClassLoc, AtClassImplLoc, SuperClassLoc);
1966*67e74705SXin Li 
1967*67e74705SXin Li   if (CheckObjCDeclScope(IMPDecl))
1968*67e74705SXin Li     return ActOnObjCContainerStartDefinition(IMPDecl);
1969*67e74705SXin Li 
1970*67e74705SXin Li   // Check that there is no duplicate implementation of this class.
1971*67e74705SXin Li   if (IDecl->getImplementation()) {
1972*67e74705SXin Li     // FIXME: Don't leak everything!
1973*67e74705SXin Li     Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName;
1974*67e74705SXin Li     Diag(IDecl->getImplementation()->getLocation(),
1975*67e74705SXin Li          diag::note_previous_definition);
1976*67e74705SXin Li     IMPDecl->setInvalidDecl();
1977*67e74705SXin Li   } else { // add it to the list.
1978*67e74705SXin Li     IDecl->setImplementation(IMPDecl);
1979*67e74705SXin Li     PushOnScopeChains(IMPDecl, TUScope);
1980*67e74705SXin Li     // Warn on implementating deprecated class under
1981*67e74705SXin Li     // -Wdeprecated-implementations flag.
1982*67e74705SXin Li     DiagnoseObjCImplementedDeprecations(*this,
1983*67e74705SXin Li                                         dyn_cast<NamedDecl>(IDecl),
1984*67e74705SXin Li                                         IMPDecl->getLocation(), 1);
1985*67e74705SXin Li   }
1986*67e74705SXin Li 
1987*67e74705SXin Li   // If the superclass has the objc_runtime_visible attribute, we
1988*67e74705SXin Li   // cannot implement a subclass of it.
1989*67e74705SXin Li   if (IDecl->getSuperClass() &&
1990*67e74705SXin Li       IDecl->getSuperClass()->hasAttr<ObjCRuntimeVisibleAttr>()) {
1991*67e74705SXin Li     Diag(ClassLoc, diag::err_objc_runtime_visible_subclass)
1992*67e74705SXin Li       << IDecl->getDeclName()
1993*67e74705SXin Li       << IDecl->getSuperClass()->getDeclName();
1994*67e74705SXin Li   }
1995*67e74705SXin Li 
1996*67e74705SXin Li   return ActOnObjCContainerStartDefinition(IMPDecl);
1997*67e74705SXin Li }
1998*67e74705SXin Li 
1999*67e74705SXin Li Sema::DeclGroupPtrTy
ActOnFinishObjCImplementation(Decl * ObjCImpDecl,ArrayRef<Decl * > Decls)2000*67e74705SXin Li Sema::ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef<Decl *> Decls) {
2001*67e74705SXin Li   SmallVector<Decl *, 64> DeclsInGroup;
2002*67e74705SXin Li   DeclsInGroup.reserve(Decls.size() + 1);
2003*67e74705SXin Li 
2004*67e74705SXin Li   for (unsigned i = 0, e = Decls.size(); i != e; ++i) {
2005*67e74705SXin Li     Decl *Dcl = Decls[i];
2006*67e74705SXin Li     if (!Dcl)
2007*67e74705SXin Li       continue;
2008*67e74705SXin Li     if (Dcl->getDeclContext()->isFileContext())
2009*67e74705SXin Li       Dcl->setTopLevelDeclInObjCContainer();
2010*67e74705SXin Li     DeclsInGroup.push_back(Dcl);
2011*67e74705SXin Li   }
2012*67e74705SXin Li 
2013*67e74705SXin Li   DeclsInGroup.push_back(ObjCImpDecl);
2014*67e74705SXin Li 
2015*67e74705SXin Li   return BuildDeclaratorGroup(DeclsInGroup, false);
2016*67e74705SXin Li }
2017*67e74705SXin Li 
CheckImplementationIvars(ObjCImplementationDecl * ImpDecl,ObjCIvarDecl ** ivars,unsigned numIvars,SourceLocation RBrace)2018*67e74705SXin Li void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
2019*67e74705SXin Li                                     ObjCIvarDecl **ivars, unsigned numIvars,
2020*67e74705SXin Li                                     SourceLocation RBrace) {
2021*67e74705SXin Li   assert(ImpDecl && "missing implementation decl");
2022*67e74705SXin Li   ObjCInterfaceDecl* IDecl = ImpDecl->getClassInterface();
2023*67e74705SXin Li   if (!IDecl)
2024*67e74705SXin Li     return;
2025*67e74705SXin Li   /// Check case of non-existing \@interface decl.
2026*67e74705SXin Li   /// (legacy objective-c \@implementation decl without an \@interface decl).
2027*67e74705SXin Li   /// Add implementations's ivar to the synthesize class's ivar list.
2028*67e74705SXin Li   if (IDecl->isImplicitInterfaceDecl()) {
2029*67e74705SXin Li     IDecl->setEndOfDefinitionLoc(RBrace);
2030*67e74705SXin Li     // Add ivar's to class's DeclContext.
2031*67e74705SXin Li     for (unsigned i = 0, e = numIvars; i != e; ++i) {
2032*67e74705SXin Li       ivars[i]->setLexicalDeclContext(ImpDecl);
2033*67e74705SXin Li       IDecl->makeDeclVisibleInContext(ivars[i]);
2034*67e74705SXin Li       ImpDecl->addDecl(ivars[i]);
2035*67e74705SXin Li     }
2036*67e74705SXin Li 
2037*67e74705SXin Li     return;
2038*67e74705SXin Li   }
2039*67e74705SXin Li   // If implementation has empty ivar list, just return.
2040*67e74705SXin Li   if (numIvars == 0)
2041*67e74705SXin Li     return;
2042*67e74705SXin Li 
2043*67e74705SXin Li   assert(ivars && "missing @implementation ivars");
2044*67e74705SXin Li   if (LangOpts.ObjCRuntime.isNonFragile()) {
2045*67e74705SXin Li     if (ImpDecl->getSuperClass())
2046*67e74705SXin Li       Diag(ImpDecl->getLocation(), diag::warn_on_superclass_use);
2047*67e74705SXin Li     for (unsigned i = 0; i < numIvars; i++) {
2048*67e74705SXin Li       ObjCIvarDecl* ImplIvar = ivars[i];
2049*67e74705SXin Li       if (const ObjCIvarDecl *ClsIvar =
2050*67e74705SXin Li             IDecl->getIvarDecl(ImplIvar->getIdentifier())) {
2051*67e74705SXin Li         Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration);
2052*67e74705SXin Li         Diag(ClsIvar->getLocation(), diag::note_previous_definition);
2053*67e74705SXin Li         continue;
2054*67e74705SXin Li       }
2055*67e74705SXin Li       // Check class extensions (unnamed categories) for duplicate ivars.
2056*67e74705SXin Li       for (const auto *CDecl : IDecl->visible_extensions()) {
2057*67e74705SXin Li         if (const ObjCIvarDecl *ClsExtIvar =
2058*67e74705SXin Li             CDecl->getIvarDecl(ImplIvar->getIdentifier())) {
2059*67e74705SXin Li           Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration);
2060*67e74705SXin Li           Diag(ClsExtIvar->getLocation(), diag::note_previous_definition);
2061*67e74705SXin Li           continue;
2062*67e74705SXin Li         }
2063*67e74705SXin Li       }
2064*67e74705SXin Li       // Instance ivar to Implementation's DeclContext.
2065*67e74705SXin Li       ImplIvar->setLexicalDeclContext(ImpDecl);
2066*67e74705SXin Li       IDecl->makeDeclVisibleInContext(ImplIvar);
2067*67e74705SXin Li       ImpDecl->addDecl(ImplIvar);
2068*67e74705SXin Li     }
2069*67e74705SXin Li     return;
2070*67e74705SXin Li   }
2071*67e74705SXin Li   // Check interface's Ivar list against those in the implementation.
2072*67e74705SXin Li   // names and types must match.
2073*67e74705SXin Li   //
2074*67e74705SXin Li   unsigned j = 0;
2075*67e74705SXin Li   ObjCInterfaceDecl::ivar_iterator
2076*67e74705SXin Li     IVI = IDecl->ivar_begin(), IVE = IDecl->ivar_end();
2077*67e74705SXin Li   for (; numIvars > 0 && IVI != IVE; ++IVI) {
2078*67e74705SXin Li     ObjCIvarDecl* ImplIvar = ivars[j++];
2079*67e74705SXin Li     ObjCIvarDecl* ClsIvar = *IVI;
2080*67e74705SXin Li     assert (ImplIvar && "missing implementation ivar");
2081*67e74705SXin Li     assert (ClsIvar && "missing class ivar");
2082*67e74705SXin Li 
2083*67e74705SXin Li     // First, make sure the types match.
2084*67e74705SXin Li     if (!Context.hasSameType(ImplIvar->getType(), ClsIvar->getType())) {
2085*67e74705SXin Li       Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type)
2086*67e74705SXin Li         << ImplIvar->getIdentifier()
2087*67e74705SXin Li         << ImplIvar->getType() << ClsIvar->getType();
2088*67e74705SXin Li       Diag(ClsIvar->getLocation(), diag::note_previous_definition);
2089*67e74705SXin Li     } else if (ImplIvar->isBitField() && ClsIvar->isBitField() &&
2090*67e74705SXin Li                ImplIvar->getBitWidthValue(Context) !=
2091*67e74705SXin Li                ClsIvar->getBitWidthValue(Context)) {
2092*67e74705SXin Li       Diag(ImplIvar->getBitWidth()->getLocStart(),
2093*67e74705SXin Li            diag::err_conflicting_ivar_bitwidth) << ImplIvar->getIdentifier();
2094*67e74705SXin Li       Diag(ClsIvar->getBitWidth()->getLocStart(),
2095*67e74705SXin Li            diag::note_previous_definition);
2096*67e74705SXin Li     }
2097*67e74705SXin Li     // Make sure the names are identical.
2098*67e74705SXin Li     if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) {
2099*67e74705SXin Li       Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name)
2100*67e74705SXin Li         << ImplIvar->getIdentifier() << ClsIvar->getIdentifier();
2101*67e74705SXin Li       Diag(ClsIvar->getLocation(), diag::note_previous_definition);
2102*67e74705SXin Li     }
2103*67e74705SXin Li     --numIvars;
2104*67e74705SXin Li   }
2105*67e74705SXin Li 
2106*67e74705SXin Li   if (numIvars > 0)
2107*67e74705SXin Li     Diag(ivars[j]->getLocation(), diag::err_inconsistent_ivar_count);
2108*67e74705SXin Li   else if (IVI != IVE)
2109*67e74705SXin Li     Diag(IVI->getLocation(), diag::err_inconsistent_ivar_count);
2110*67e74705SXin Li }
2111*67e74705SXin Li 
WarnUndefinedMethod(Sema & S,SourceLocation ImpLoc,ObjCMethodDecl * method,bool & IncompleteImpl,unsigned DiagID,NamedDecl * NeededFor=nullptr)2112*67e74705SXin Li static void WarnUndefinedMethod(Sema &S, SourceLocation ImpLoc,
2113*67e74705SXin Li                                 ObjCMethodDecl *method,
2114*67e74705SXin Li                                 bool &IncompleteImpl,
2115*67e74705SXin Li                                 unsigned DiagID,
2116*67e74705SXin Li                                 NamedDecl *NeededFor = nullptr) {
2117*67e74705SXin Li   // No point warning no definition of method which is 'unavailable'.
2118*67e74705SXin Li   switch (method->getAvailability()) {
2119*67e74705SXin Li   case AR_Available:
2120*67e74705SXin Li   case AR_Deprecated:
2121*67e74705SXin Li     break;
2122*67e74705SXin Li 
2123*67e74705SXin Li       // Don't warn about unavailable or not-yet-introduced methods.
2124*67e74705SXin Li   case AR_NotYetIntroduced:
2125*67e74705SXin Li   case AR_Unavailable:
2126*67e74705SXin Li     return;
2127*67e74705SXin Li   }
2128*67e74705SXin Li 
2129*67e74705SXin Li   // FIXME: For now ignore 'IncompleteImpl'.
2130*67e74705SXin Li   // Previously we grouped all unimplemented methods under a single
2131*67e74705SXin Li   // warning, but some users strongly voiced that they would prefer
2132*67e74705SXin Li   // separate warnings.  We will give that approach a try, as that
2133*67e74705SXin Li   // matches what we do with protocols.
2134*67e74705SXin Li   {
2135*67e74705SXin Li     const Sema::SemaDiagnosticBuilder &B = S.Diag(ImpLoc, DiagID);
2136*67e74705SXin Li     B << method;
2137*67e74705SXin Li     if (NeededFor)
2138*67e74705SXin Li       B << NeededFor;
2139*67e74705SXin Li   }
2140*67e74705SXin Li 
2141*67e74705SXin Li   // Issue a note to the original declaration.
2142*67e74705SXin Li   SourceLocation MethodLoc = method->getLocStart();
2143*67e74705SXin Li   if (MethodLoc.isValid())
2144*67e74705SXin Li     S.Diag(MethodLoc, diag::note_method_declared_at) << method;
2145*67e74705SXin Li }
2146*67e74705SXin Li 
2147*67e74705SXin Li /// Determines if type B can be substituted for type A.  Returns true if we can
2148*67e74705SXin Li /// guarantee that anything that the user will do to an object of type A can
2149*67e74705SXin Li /// also be done to an object of type B.  This is trivially true if the two
2150*67e74705SXin Li /// types are the same, or if B is a subclass of A.  It becomes more complex
2151*67e74705SXin Li /// in cases where protocols are involved.
2152*67e74705SXin Li ///
2153*67e74705SXin Li /// Object types in Objective-C describe the minimum requirements for an
2154*67e74705SXin Li /// object, rather than providing a complete description of a type.  For
2155*67e74705SXin Li /// example, if A is a subclass of B, then B* may refer to an instance of A.
2156*67e74705SXin Li /// The principle of substitutability means that we may use an instance of A
2157*67e74705SXin Li /// anywhere that we may use an instance of B - it will implement all of the
2158*67e74705SXin Li /// ivars of B and all of the methods of B.
2159*67e74705SXin Li ///
2160*67e74705SXin Li /// This substitutability is important when type checking methods, because
2161*67e74705SXin Li /// the implementation may have stricter type definitions than the interface.
2162*67e74705SXin Li /// The interface specifies minimum requirements, but the implementation may
2163*67e74705SXin Li /// have more accurate ones.  For example, a method may privately accept
2164*67e74705SXin Li /// instances of B, but only publish that it accepts instances of A.  Any
2165*67e74705SXin Li /// object passed to it will be type checked against B, and so will implicitly
2166*67e74705SXin Li /// by a valid A*.  Similarly, a method may return a subclass of the class that
2167*67e74705SXin Li /// it is declared as returning.
2168*67e74705SXin Li ///
2169*67e74705SXin Li /// This is most important when considering subclassing.  A method in a
2170*67e74705SXin Li /// subclass must accept any object as an argument that its superclass's
2171*67e74705SXin Li /// implementation accepts.  It may, however, accept a more general type
2172*67e74705SXin Li /// without breaking substitutability (i.e. you can still use the subclass
2173*67e74705SXin Li /// anywhere that you can use the superclass, but not vice versa).  The
2174*67e74705SXin Li /// converse requirement applies to return types: the return type for a
2175*67e74705SXin Li /// subclass method must be a valid object of the kind that the superclass
2176*67e74705SXin Li /// advertises, but it may be specified more accurately.  This avoids the need
2177*67e74705SXin Li /// for explicit down-casting by callers.
2178*67e74705SXin Li ///
2179*67e74705SXin Li /// Note: This is a stricter requirement than for assignment.
isObjCTypeSubstitutable(ASTContext & Context,const ObjCObjectPointerType * A,const ObjCObjectPointerType * B,bool rejectId)2180*67e74705SXin Li static bool isObjCTypeSubstitutable(ASTContext &Context,
2181*67e74705SXin Li                                     const ObjCObjectPointerType *A,
2182*67e74705SXin Li                                     const ObjCObjectPointerType *B,
2183*67e74705SXin Li                                     bool rejectId) {
2184*67e74705SXin Li   // Reject a protocol-unqualified id.
2185*67e74705SXin Li   if (rejectId && B->isObjCIdType()) return false;
2186*67e74705SXin Li 
2187*67e74705SXin Li   // If B is a qualified id, then A must also be a qualified id and it must
2188*67e74705SXin Li   // implement all of the protocols in B.  It may not be a qualified class.
2189*67e74705SXin Li   // For example, MyClass<A> can be assigned to id<A>, but MyClass<A> is a
2190*67e74705SXin Li   // stricter definition so it is not substitutable for id<A>.
2191*67e74705SXin Li   if (B->isObjCQualifiedIdType()) {
2192*67e74705SXin Li     return A->isObjCQualifiedIdType() &&
2193*67e74705SXin Li            Context.ObjCQualifiedIdTypesAreCompatible(QualType(A, 0),
2194*67e74705SXin Li                                                      QualType(B,0),
2195*67e74705SXin Li                                                      false);
2196*67e74705SXin Li   }
2197*67e74705SXin Li 
2198*67e74705SXin Li   /*
2199*67e74705SXin Li   // id is a special type that bypasses type checking completely.  We want a
2200*67e74705SXin Li   // warning when it is used in one place but not another.
2201*67e74705SXin Li   if (C.isObjCIdType(A) || C.isObjCIdType(B)) return false;
2202*67e74705SXin Li 
2203*67e74705SXin Li 
2204*67e74705SXin Li   // If B is a qualified id, then A must also be a qualified id (which it isn't
2205*67e74705SXin Li   // if we've got this far)
2206*67e74705SXin Li   if (B->isObjCQualifiedIdType()) return false;
2207*67e74705SXin Li   */
2208*67e74705SXin Li 
2209*67e74705SXin Li   // Now we know that A and B are (potentially-qualified) class types.  The
2210*67e74705SXin Li   // normal rules for assignment apply.
2211*67e74705SXin Li   return Context.canAssignObjCInterfaces(A, B);
2212*67e74705SXin Li }
2213*67e74705SXin Li 
getTypeRange(TypeSourceInfo * TSI)2214*67e74705SXin Li static SourceRange getTypeRange(TypeSourceInfo *TSI) {
2215*67e74705SXin Li   return (TSI ? TSI->getTypeLoc().getSourceRange() : SourceRange());
2216*67e74705SXin Li }
2217*67e74705SXin Li 
2218*67e74705SXin Li /// Determine whether two set of Objective-C declaration qualifiers conflict.
objcModifiersConflict(Decl::ObjCDeclQualifier x,Decl::ObjCDeclQualifier y)2219*67e74705SXin Li static bool objcModifiersConflict(Decl::ObjCDeclQualifier x,
2220*67e74705SXin Li                                   Decl::ObjCDeclQualifier y) {
2221*67e74705SXin Li   return (x & ~Decl::OBJC_TQ_CSNullability) !=
2222*67e74705SXin Li          (y & ~Decl::OBJC_TQ_CSNullability);
2223*67e74705SXin Li }
2224*67e74705SXin Li 
CheckMethodOverrideReturn(Sema & S,ObjCMethodDecl * MethodImpl,ObjCMethodDecl * MethodDecl,bool IsProtocolMethodDecl,bool IsOverridingMode,bool Warn)2225*67e74705SXin Li static bool CheckMethodOverrideReturn(Sema &S,
2226*67e74705SXin Li                                       ObjCMethodDecl *MethodImpl,
2227*67e74705SXin Li                                       ObjCMethodDecl *MethodDecl,
2228*67e74705SXin Li                                       bool IsProtocolMethodDecl,
2229*67e74705SXin Li                                       bool IsOverridingMode,
2230*67e74705SXin Li                                       bool Warn) {
2231*67e74705SXin Li   if (IsProtocolMethodDecl &&
2232*67e74705SXin Li       objcModifiersConflict(MethodDecl->getObjCDeclQualifier(),
2233*67e74705SXin Li                             MethodImpl->getObjCDeclQualifier())) {
2234*67e74705SXin Li     if (Warn) {
2235*67e74705SXin Li       S.Diag(MethodImpl->getLocation(),
2236*67e74705SXin Li              (IsOverridingMode
2237*67e74705SXin Li                   ? diag::warn_conflicting_overriding_ret_type_modifiers
2238*67e74705SXin Li                   : diag::warn_conflicting_ret_type_modifiers))
2239*67e74705SXin Li           << MethodImpl->getDeclName()
2240*67e74705SXin Li           << MethodImpl->getReturnTypeSourceRange();
2241*67e74705SXin Li       S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration)
2242*67e74705SXin Li           << MethodDecl->getReturnTypeSourceRange();
2243*67e74705SXin Li     }
2244*67e74705SXin Li     else
2245*67e74705SXin Li       return false;
2246*67e74705SXin Li   }
2247*67e74705SXin Li   if (Warn && IsOverridingMode &&
2248*67e74705SXin Li       !isa<ObjCImplementationDecl>(MethodImpl->getDeclContext()) &&
2249*67e74705SXin Li       !S.Context.hasSameNullabilityTypeQualifier(MethodImpl->getReturnType(),
2250*67e74705SXin Li                                                  MethodDecl->getReturnType(),
2251*67e74705SXin Li                                                  false)) {
2252*67e74705SXin Li     auto nullabilityMethodImpl =
2253*67e74705SXin Li       *MethodImpl->getReturnType()->getNullability(S.Context);
2254*67e74705SXin Li     auto nullabilityMethodDecl =
2255*67e74705SXin Li       *MethodDecl->getReturnType()->getNullability(S.Context);
2256*67e74705SXin Li       S.Diag(MethodImpl->getLocation(),
2257*67e74705SXin Li              diag::warn_conflicting_nullability_attr_overriding_ret_types)
2258*67e74705SXin Li         << DiagNullabilityKind(
2259*67e74705SXin Li              nullabilityMethodImpl,
2260*67e74705SXin Li              ((MethodImpl->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability)
2261*67e74705SXin Li               != 0))
2262*67e74705SXin Li         << DiagNullabilityKind(
2263*67e74705SXin Li              nullabilityMethodDecl,
2264*67e74705SXin Li              ((MethodDecl->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability)
2265*67e74705SXin Li                 != 0));
2266*67e74705SXin Li       S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration);
2267*67e74705SXin Li   }
2268*67e74705SXin Li 
2269*67e74705SXin Li   if (S.Context.hasSameUnqualifiedType(MethodImpl->getReturnType(),
2270*67e74705SXin Li                                        MethodDecl->getReturnType()))
2271*67e74705SXin Li     return true;
2272*67e74705SXin Li   if (!Warn)
2273*67e74705SXin Li     return false;
2274*67e74705SXin Li 
2275*67e74705SXin Li   unsigned DiagID =
2276*67e74705SXin Li     IsOverridingMode ? diag::warn_conflicting_overriding_ret_types
2277*67e74705SXin Li                      : diag::warn_conflicting_ret_types;
2278*67e74705SXin Li 
2279*67e74705SXin Li   // Mismatches between ObjC pointers go into a different warning
2280*67e74705SXin Li   // category, and sometimes they're even completely whitelisted.
2281*67e74705SXin Li   if (const ObjCObjectPointerType *ImplPtrTy =
2282*67e74705SXin Li           MethodImpl->getReturnType()->getAs<ObjCObjectPointerType>()) {
2283*67e74705SXin Li     if (const ObjCObjectPointerType *IfacePtrTy =
2284*67e74705SXin Li             MethodDecl->getReturnType()->getAs<ObjCObjectPointerType>()) {
2285*67e74705SXin Li       // Allow non-matching return types as long as they don't violate
2286*67e74705SXin Li       // the principle of substitutability.  Specifically, we permit
2287*67e74705SXin Li       // return types that are subclasses of the declared return type,
2288*67e74705SXin Li       // or that are more-qualified versions of the declared type.
2289*67e74705SXin Li       if (isObjCTypeSubstitutable(S.Context, IfacePtrTy, ImplPtrTy, false))
2290*67e74705SXin Li         return false;
2291*67e74705SXin Li 
2292*67e74705SXin Li       DiagID =
2293*67e74705SXin Li         IsOverridingMode ? diag::warn_non_covariant_overriding_ret_types
2294*67e74705SXin Li                          : diag::warn_non_covariant_ret_types;
2295*67e74705SXin Li     }
2296*67e74705SXin Li   }
2297*67e74705SXin Li 
2298*67e74705SXin Li   S.Diag(MethodImpl->getLocation(), DiagID)
2299*67e74705SXin Li       << MethodImpl->getDeclName() << MethodDecl->getReturnType()
2300*67e74705SXin Li       << MethodImpl->getReturnType()
2301*67e74705SXin Li       << MethodImpl->getReturnTypeSourceRange();
2302*67e74705SXin Li   S.Diag(MethodDecl->getLocation(), IsOverridingMode
2303*67e74705SXin Li                                         ? diag::note_previous_declaration
2304*67e74705SXin Li                                         : diag::note_previous_definition)
2305*67e74705SXin Li       << MethodDecl->getReturnTypeSourceRange();
2306*67e74705SXin Li   return false;
2307*67e74705SXin Li }
2308*67e74705SXin Li 
CheckMethodOverrideParam(Sema & S,ObjCMethodDecl * MethodImpl,ObjCMethodDecl * MethodDecl,ParmVarDecl * ImplVar,ParmVarDecl * IfaceVar,bool IsProtocolMethodDecl,bool IsOverridingMode,bool Warn)2309*67e74705SXin Li static bool CheckMethodOverrideParam(Sema &S,
2310*67e74705SXin Li                                      ObjCMethodDecl *MethodImpl,
2311*67e74705SXin Li                                      ObjCMethodDecl *MethodDecl,
2312*67e74705SXin Li                                      ParmVarDecl *ImplVar,
2313*67e74705SXin Li                                      ParmVarDecl *IfaceVar,
2314*67e74705SXin Li                                      bool IsProtocolMethodDecl,
2315*67e74705SXin Li                                      bool IsOverridingMode,
2316*67e74705SXin Li                                      bool Warn) {
2317*67e74705SXin Li   if (IsProtocolMethodDecl &&
2318*67e74705SXin Li       objcModifiersConflict(ImplVar->getObjCDeclQualifier(),
2319*67e74705SXin Li                             IfaceVar->getObjCDeclQualifier())) {
2320*67e74705SXin Li     if (Warn) {
2321*67e74705SXin Li       if (IsOverridingMode)
2322*67e74705SXin Li         S.Diag(ImplVar->getLocation(),
2323*67e74705SXin Li                diag::warn_conflicting_overriding_param_modifiers)
2324*67e74705SXin Li             << getTypeRange(ImplVar->getTypeSourceInfo())
2325*67e74705SXin Li             << MethodImpl->getDeclName();
2326*67e74705SXin Li       else S.Diag(ImplVar->getLocation(),
2327*67e74705SXin Li              diag::warn_conflicting_param_modifiers)
2328*67e74705SXin Li           << getTypeRange(ImplVar->getTypeSourceInfo())
2329*67e74705SXin Li           << MethodImpl->getDeclName();
2330*67e74705SXin Li       S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration)
2331*67e74705SXin Li           << getTypeRange(IfaceVar->getTypeSourceInfo());
2332*67e74705SXin Li     }
2333*67e74705SXin Li     else
2334*67e74705SXin Li       return false;
2335*67e74705SXin Li   }
2336*67e74705SXin Li 
2337*67e74705SXin Li   QualType ImplTy = ImplVar->getType();
2338*67e74705SXin Li   QualType IfaceTy = IfaceVar->getType();
2339*67e74705SXin Li   if (Warn && IsOverridingMode &&
2340*67e74705SXin Li       !isa<ObjCImplementationDecl>(MethodImpl->getDeclContext()) &&
2341*67e74705SXin Li       !S.Context.hasSameNullabilityTypeQualifier(ImplTy, IfaceTy, true)) {
2342*67e74705SXin Li     S.Diag(ImplVar->getLocation(),
2343*67e74705SXin Li            diag::warn_conflicting_nullability_attr_overriding_param_types)
2344*67e74705SXin Li       << DiagNullabilityKind(
2345*67e74705SXin Li            *ImplTy->getNullability(S.Context),
2346*67e74705SXin Li            ((ImplVar->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability)
2347*67e74705SXin Li             != 0))
2348*67e74705SXin Li       << DiagNullabilityKind(
2349*67e74705SXin Li            *IfaceTy->getNullability(S.Context),
2350*67e74705SXin Li            ((IfaceVar->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability)
2351*67e74705SXin Li             != 0));
2352*67e74705SXin Li     S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration);
2353*67e74705SXin Li   }
2354*67e74705SXin Li   if (S.Context.hasSameUnqualifiedType(ImplTy, IfaceTy))
2355*67e74705SXin Li     return true;
2356*67e74705SXin Li 
2357*67e74705SXin Li   if (!Warn)
2358*67e74705SXin Li     return false;
2359*67e74705SXin Li   unsigned DiagID =
2360*67e74705SXin Li     IsOverridingMode ? diag::warn_conflicting_overriding_param_types
2361*67e74705SXin Li                      : diag::warn_conflicting_param_types;
2362*67e74705SXin Li 
2363*67e74705SXin Li   // Mismatches between ObjC pointers go into a different warning
2364*67e74705SXin Li   // category, and sometimes they're even completely whitelisted.
2365*67e74705SXin Li   if (const ObjCObjectPointerType *ImplPtrTy =
2366*67e74705SXin Li         ImplTy->getAs<ObjCObjectPointerType>()) {
2367*67e74705SXin Li     if (const ObjCObjectPointerType *IfacePtrTy =
2368*67e74705SXin Li           IfaceTy->getAs<ObjCObjectPointerType>()) {
2369*67e74705SXin Li       // Allow non-matching argument types as long as they don't
2370*67e74705SXin Li       // violate the principle of substitutability.  Specifically, the
2371*67e74705SXin Li       // implementation must accept any objects that the superclass
2372*67e74705SXin Li       // accepts, however it may also accept others.
2373*67e74705SXin Li       if (isObjCTypeSubstitutable(S.Context, ImplPtrTy, IfacePtrTy, true))
2374*67e74705SXin Li         return false;
2375*67e74705SXin Li 
2376*67e74705SXin Li       DiagID =
2377*67e74705SXin Li       IsOverridingMode ? diag::warn_non_contravariant_overriding_param_types
2378*67e74705SXin Li                        : diag::warn_non_contravariant_param_types;
2379*67e74705SXin Li     }
2380*67e74705SXin Li   }
2381*67e74705SXin Li 
2382*67e74705SXin Li   S.Diag(ImplVar->getLocation(), DiagID)
2383*67e74705SXin Li     << getTypeRange(ImplVar->getTypeSourceInfo())
2384*67e74705SXin Li     << MethodImpl->getDeclName() << IfaceTy << ImplTy;
2385*67e74705SXin Li   S.Diag(IfaceVar->getLocation(),
2386*67e74705SXin Li          (IsOverridingMode ? diag::note_previous_declaration
2387*67e74705SXin Li                            : diag::note_previous_definition))
2388*67e74705SXin Li     << getTypeRange(IfaceVar->getTypeSourceInfo());
2389*67e74705SXin Li   return false;
2390*67e74705SXin Li }
2391*67e74705SXin Li 
2392*67e74705SXin Li /// In ARC, check whether the conventional meanings of the two methods
2393*67e74705SXin Li /// match.  If they don't, it's a hard error.
checkMethodFamilyMismatch(Sema & S,ObjCMethodDecl * impl,ObjCMethodDecl * decl)2394*67e74705SXin Li static bool checkMethodFamilyMismatch(Sema &S, ObjCMethodDecl *impl,
2395*67e74705SXin Li                                       ObjCMethodDecl *decl) {
2396*67e74705SXin Li   ObjCMethodFamily implFamily = impl->getMethodFamily();
2397*67e74705SXin Li   ObjCMethodFamily declFamily = decl->getMethodFamily();
2398*67e74705SXin Li   if (implFamily == declFamily) return false;
2399*67e74705SXin Li 
2400*67e74705SXin Li   // Since conventions are sorted by selector, the only possibility is
2401*67e74705SXin Li   // that the types differ enough to cause one selector or the other
2402*67e74705SXin Li   // to fall out of the family.
2403*67e74705SXin Li   assert(implFamily == OMF_None || declFamily == OMF_None);
2404*67e74705SXin Li 
2405*67e74705SXin Li   // No further diagnostics required on invalid declarations.
2406*67e74705SXin Li   if (impl->isInvalidDecl() || decl->isInvalidDecl()) return true;
2407*67e74705SXin Li 
2408*67e74705SXin Li   const ObjCMethodDecl *unmatched = impl;
2409*67e74705SXin Li   ObjCMethodFamily family = declFamily;
2410*67e74705SXin Li   unsigned errorID = diag::err_arc_lost_method_convention;
2411*67e74705SXin Li   unsigned noteID = diag::note_arc_lost_method_convention;
2412*67e74705SXin Li   if (declFamily == OMF_None) {
2413*67e74705SXin Li     unmatched = decl;
2414*67e74705SXin Li     family = implFamily;
2415*67e74705SXin Li     errorID = diag::err_arc_gained_method_convention;
2416*67e74705SXin Li     noteID = diag::note_arc_gained_method_convention;
2417*67e74705SXin Li   }
2418*67e74705SXin Li 
2419*67e74705SXin Li   // Indexes into a %select clause in the diagnostic.
2420*67e74705SXin Li   enum FamilySelector {
2421*67e74705SXin Li     F_alloc, F_copy, F_mutableCopy = F_copy, F_init, F_new
2422*67e74705SXin Li   };
2423*67e74705SXin Li   FamilySelector familySelector = FamilySelector();
2424*67e74705SXin Li 
2425*67e74705SXin Li   switch (family) {
2426*67e74705SXin Li   case OMF_None: llvm_unreachable("logic error, no method convention");
2427*67e74705SXin Li   case OMF_retain:
2428*67e74705SXin Li   case OMF_release:
2429*67e74705SXin Li   case OMF_autorelease:
2430*67e74705SXin Li   case OMF_dealloc:
2431*67e74705SXin Li   case OMF_finalize:
2432*67e74705SXin Li   case OMF_retainCount:
2433*67e74705SXin Li   case OMF_self:
2434*67e74705SXin Li   case OMF_initialize:
2435*67e74705SXin Li   case OMF_performSelector:
2436*67e74705SXin Li     // Mismatches for these methods don't change ownership
2437*67e74705SXin Li     // conventions, so we don't care.
2438*67e74705SXin Li     return false;
2439*67e74705SXin Li 
2440*67e74705SXin Li   case OMF_init: familySelector = F_init; break;
2441*67e74705SXin Li   case OMF_alloc: familySelector = F_alloc; break;
2442*67e74705SXin Li   case OMF_copy: familySelector = F_copy; break;
2443*67e74705SXin Li   case OMF_mutableCopy: familySelector = F_mutableCopy; break;
2444*67e74705SXin Li   case OMF_new: familySelector = F_new; break;
2445*67e74705SXin Li   }
2446*67e74705SXin Li 
2447*67e74705SXin Li   enum ReasonSelector { R_NonObjectReturn, R_UnrelatedReturn };
2448*67e74705SXin Li   ReasonSelector reasonSelector;
2449*67e74705SXin Li 
2450*67e74705SXin Li   // The only reason these methods don't fall within their families is
2451*67e74705SXin Li   // due to unusual result types.
2452*67e74705SXin Li   if (unmatched->getReturnType()->isObjCObjectPointerType()) {
2453*67e74705SXin Li     reasonSelector = R_UnrelatedReturn;
2454*67e74705SXin Li   } else {
2455*67e74705SXin Li     reasonSelector = R_NonObjectReturn;
2456*67e74705SXin Li   }
2457*67e74705SXin Li 
2458*67e74705SXin Li   S.Diag(impl->getLocation(), errorID) << int(familySelector) << int(reasonSelector);
2459*67e74705SXin Li   S.Diag(decl->getLocation(), noteID) << int(familySelector) << int(reasonSelector);
2460*67e74705SXin Li 
2461*67e74705SXin Li   return true;
2462*67e74705SXin Li }
2463*67e74705SXin Li 
WarnConflictingTypedMethods(ObjCMethodDecl * ImpMethodDecl,ObjCMethodDecl * MethodDecl,bool IsProtocolMethodDecl)2464*67e74705SXin Li void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl,
2465*67e74705SXin Li                                        ObjCMethodDecl *MethodDecl,
2466*67e74705SXin Li                                        bool IsProtocolMethodDecl) {
2467*67e74705SXin Li   if (getLangOpts().ObjCAutoRefCount &&
2468*67e74705SXin Li       checkMethodFamilyMismatch(*this, ImpMethodDecl, MethodDecl))
2469*67e74705SXin Li     return;
2470*67e74705SXin Li 
2471*67e74705SXin Li   CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl,
2472*67e74705SXin Li                             IsProtocolMethodDecl, false,
2473*67e74705SXin Li                             true);
2474*67e74705SXin Li 
2475*67e74705SXin Li   for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
2476*67e74705SXin Li        IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(),
2477*67e74705SXin Li        EF = MethodDecl->param_end();
2478*67e74705SXin Li        IM != EM && IF != EF; ++IM, ++IF) {
2479*67e74705SXin Li     CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl, *IM, *IF,
2480*67e74705SXin Li                              IsProtocolMethodDecl, false, true);
2481*67e74705SXin Li   }
2482*67e74705SXin Li 
2483*67e74705SXin Li   if (ImpMethodDecl->isVariadic() != MethodDecl->isVariadic()) {
2484*67e74705SXin Li     Diag(ImpMethodDecl->getLocation(),
2485*67e74705SXin Li          diag::warn_conflicting_variadic);
2486*67e74705SXin Li     Diag(MethodDecl->getLocation(), diag::note_previous_declaration);
2487*67e74705SXin Li   }
2488*67e74705SXin Li }
2489*67e74705SXin Li 
CheckConflictingOverridingMethod(ObjCMethodDecl * Method,ObjCMethodDecl * Overridden,bool IsProtocolMethodDecl)2490*67e74705SXin Li void Sema::CheckConflictingOverridingMethod(ObjCMethodDecl *Method,
2491*67e74705SXin Li                                        ObjCMethodDecl *Overridden,
2492*67e74705SXin Li                                        bool IsProtocolMethodDecl) {
2493*67e74705SXin Li 
2494*67e74705SXin Li   CheckMethodOverrideReturn(*this, Method, Overridden,
2495*67e74705SXin Li                             IsProtocolMethodDecl, true,
2496*67e74705SXin Li                             true);
2497*67e74705SXin Li 
2498*67e74705SXin Li   for (ObjCMethodDecl::param_iterator IM = Method->param_begin(),
2499*67e74705SXin Li        IF = Overridden->param_begin(), EM = Method->param_end(),
2500*67e74705SXin Li        EF = Overridden->param_end();
2501*67e74705SXin Li        IM != EM && IF != EF; ++IM, ++IF) {
2502*67e74705SXin Li     CheckMethodOverrideParam(*this, Method, Overridden, *IM, *IF,
2503*67e74705SXin Li                              IsProtocolMethodDecl, true, true);
2504*67e74705SXin Li   }
2505*67e74705SXin Li 
2506*67e74705SXin Li   if (Method->isVariadic() != Overridden->isVariadic()) {
2507*67e74705SXin Li     Diag(Method->getLocation(),
2508*67e74705SXin Li          diag::warn_conflicting_overriding_variadic);
2509*67e74705SXin Li     Diag(Overridden->getLocation(), diag::note_previous_declaration);
2510*67e74705SXin Li   }
2511*67e74705SXin Li }
2512*67e74705SXin Li 
2513*67e74705SXin Li /// WarnExactTypedMethods - This routine issues a warning if method
2514*67e74705SXin Li /// implementation declaration matches exactly that of its declaration.
WarnExactTypedMethods(ObjCMethodDecl * ImpMethodDecl,ObjCMethodDecl * MethodDecl,bool IsProtocolMethodDecl)2515*67e74705SXin Li void Sema::WarnExactTypedMethods(ObjCMethodDecl *ImpMethodDecl,
2516*67e74705SXin Li                                  ObjCMethodDecl *MethodDecl,
2517*67e74705SXin Li                                  bool IsProtocolMethodDecl) {
2518*67e74705SXin Li   // don't issue warning when protocol method is optional because primary
2519*67e74705SXin Li   // class is not required to implement it and it is safe for protocol
2520*67e74705SXin Li   // to implement it.
2521*67e74705SXin Li   if (MethodDecl->getImplementationControl() == ObjCMethodDecl::Optional)
2522*67e74705SXin Li     return;
2523*67e74705SXin Li   // don't issue warning when primary class's method is
2524*67e74705SXin Li   // depecated/unavailable.
2525*67e74705SXin Li   if (MethodDecl->hasAttr<UnavailableAttr>() ||
2526*67e74705SXin Li       MethodDecl->hasAttr<DeprecatedAttr>())
2527*67e74705SXin Li     return;
2528*67e74705SXin Li 
2529*67e74705SXin Li   bool match = CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl,
2530*67e74705SXin Li                                       IsProtocolMethodDecl, false, false);
2531*67e74705SXin Li   if (match)
2532*67e74705SXin Li     for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
2533*67e74705SXin Li          IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(),
2534*67e74705SXin Li          EF = MethodDecl->param_end();
2535*67e74705SXin Li          IM != EM && IF != EF; ++IM, ++IF) {
2536*67e74705SXin Li       match = CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl,
2537*67e74705SXin Li                                        *IM, *IF,
2538*67e74705SXin Li                                        IsProtocolMethodDecl, false, false);
2539*67e74705SXin Li       if (!match)
2540*67e74705SXin Li         break;
2541*67e74705SXin Li     }
2542*67e74705SXin Li   if (match)
2543*67e74705SXin Li     match = (ImpMethodDecl->isVariadic() == MethodDecl->isVariadic());
2544*67e74705SXin Li   if (match)
2545*67e74705SXin Li     match = !(MethodDecl->isClassMethod() &&
2546*67e74705SXin Li               MethodDecl->getSelector() == GetNullarySelector("load", Context));
2547*67e74705SXin Li 
2548*67e74705SXin Li   if (match) {
2549*67e74705SXin Li     Diag(ImpMethodDecl->getLocation(),
2550*67e74705SXin Li          diag::warn_category_method_impl_match);
2551*67e74705SXin Li     Diag(MethodDecl->getLocation(), diag::note_method_declared_at)
2552*67e74705SXin Li       << MethodDecl->getDeclName();
2553*67e74705SXin Li   }
2554*67e74705SXin Li }
2555*67e74705SXin Li 
2556*67e74705SXin Li /// FIXME: Type hierarchies in Objective-C can be deep. We could most likely
2557*67e74705SXin Li /// improve the efficiency of selector lookups and type checking by associating
2558*67e74705SXin Li /// with each protocol / interface / category the flattened instance tables. If
2559*67e74705SXin Li /// we used an immutable set to keep the table then it wouldn't add significant
2560*67e74705SXin Li /// memory cost and it would be handy for lookups.
2561*67e74705SXin Li 
2562*67e74705SXin Li typedef llvm::DenseSet<IdentifierInfo*> ProtocolNameSet;
2563*67e74705SXin Li typedef std::unique_ptr<ProtocolNameSet> LazyProtocolNameSet;
2564*67e74705SXin Li 
findProtocolsWithExplicitImpls(const ObjCProtocolDecl * PDecl,ProtocolNameSet & PNS)2565*67e74705SXin Li static void findProtocolsWithExplicitImpls(const ObjCProtocolDecl *PDecl,
2566*67e74705SXin Li                                            ProtocolNameSet &PNS) {
2567*67e74705SXin Li   if (PDecl->hasAttr<ObjCExplicitProtocolImplAttr>())
2568*67e74705SXin Li     PNS.insert(PDecl->getIdentifier());
2569*67e74705SXin Li   for (const auto *PI : PDecl->protocols())
2570*67e74705SXin Li     findProtocolsWithExplicitImpls(PI, PNS);
2571*67e74705SXin Li }
2572*67e74705SXin Li 
2573*67e74705SXin Li /// Recursively populates a set with all conformed protocols in a class
2574*67e74705SXin Li /// hierarchy that have the 'objc_protocol_requires_explicit_implementation'
2575*67e74705SXin Li /// attribute.
findProtocolsWithExplicitImpls(const ObjCInterfaceDecl * Super,ProtocolNameSet & PNS)2576*67e74705SXin Li static void findProtocolsWithExplicitImpls(const ObjCInterfaceDecl *Super,
2577*67e74705SXin Li                                            ProtocolNameSet &PNS) {
2578*67e74705SXin Li   if (!Super)
2579*67e74705SXin Li     return;
2580*67e74705SXin Li 
2581*67e74705SXin Li   for (const auto *I : Super->all_referenced_protocols())
2582*67e74705SXin Li     findProtocolsWithExplicitImpls(I, PNS);
2583*67e74705SXin Li 
2584*67e74705SXin Li   findProtocolsWithExplicitImpls(Super->getSuperClass(), PNS);
2585*67e74705SXin Li }
2586*67e74705SXin Li 
2587*67e74705SXin Li /// CheckProtocolMethodDefs - This routine checks unimplemented methods
2588*67e74705SXin Li /// Declared in protocol, and those referenced by it.
CheckProtocolMethodDefs(Sema & S,SourceLocation ImpLoc,ObjCProtocolDecl * PDecl,bool & IncompleteImpl,const Sema::SelectorSet & InsMap,const Sema::SelectorSet & ClsMap,ObjCContainerDecl * CDecl,LazyProtocolNameSet & ProtocolsExplictImpl)2589*67e74705SXin Li static void CheckProtocolMethodDefs(Sema &S,
2590*67e74705SXin Li                                     SourceLocation ImpLoc,
2591*67e74705SXin Li                                     ObjCProtocolDecl *PDecl,
2592*67e74705SXin Li                                     bool& IncompleteImpl,
2593*67e74705SXin Li                                     const Sema::SelectorSet &InsMap,
2594*67e74705SXin Li                                     const Sema::SelectorSet &ClsMap,
2595*67e74705SXin Li                                     ObjCContainerDecl *CDecl,
2596*67e74705SXin Li                                     LazyProtocolNameSet &ProtocolsExplictImpl) {
2597*67e74705SXin Li   ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl);
2598*67e74705SXin Li   ObjCInterfaceDecl *IDecl = C ? C->getClassInterface()
2599*67e74705SXin Li                                : dyn_cast<ObjCInterfaceDecl>(CDecl);
2600*67e74705SXin Li   assert (IDecl && "CheckProtocolMethodDefs - IDecl is null");
2601*67e74705SXin Li 
2602*67e74705SXin Li   ObjCInterfaceDecl *Super = IDecl->getSuperClass();
2603*67e74705SXin Li   ObjCInterfaceDecl *NSIDecl = nullptr;
2604*67e74705SXin Li 
2605*67e74705SXin Li   // If this protocol is marked 'objc_protocol_requires_explicit_implementation'
2606*67e74705SXin Li   // then we should check if any class in the super class hierarchy also
2607*67e74705SXin Li   // conforms to this protocol, either directly or via protocol inheritance.
2608*67e74705SXin Li   // If so, we can skip checking this protocol completely because we
2609*67e74705SXin Li   // know that a parent class already satisfies this protocol.
2610*67e74705SXin Li   //
2611*67e74705SXin Li   // Note: we could generalize this logic for all protocols, and merely
2612*67e74705SXin Li   // add the limit on looking at the super class chain for just
2613*67e74705SXin Li   // specially marked protocols.  This may be a good optimization.  This
2614*67e74705SXin Li   // change is restricted to 'objc_protocol_requires_explicit_implementation'
2615*67e74705SXin Li   // protocols for now for controlled evaluation.
2616*67e74705SXin Li   if (PDecl->hasAttr<ObjCExplicitProtocolImplAttr>()) {
2617*67e74705SXin Li     if (!ProtocolsExplictImpl) {
2618*67e74705SXin Li       ProtocolsExplictImpl.reset(new ProtocolNameSet);
2619*67e74705SXin Li       findProtocolsWithExplicitImpls(Super, *ProtocolsExplictImpl);
2620*67e74705SXin Li     }
2621*67e74705SXin Li     if (ProtocolsExplictImpl->find(PDecl->getIdentifier()) !=
2622*67e74705SXin Li         ProtocolsExplictImpl->end())
2623*67e74705SXin Li       return;
2624*67e74705SXin Li 
2625*67e74705SXin Li     // If no super class conforms to the protocol, we should not search
2626*67e74705SXin Li     // for methods in the super class to implicitly satisfy the protocol.
2627*67e74705SXin Li     Super = nullptr;
2628*67e74705SXin Li   }
2629*67e74705SXin Li 
2630*67e74705SXin Li   if (S.getLangOpts().ObjCRuntime.isNeXTFamily()) {
2631*67e74705SXin Li     // check to see if class implements forwardInvocation method and objects
2632*67e74705SXin Li     // of this class are derived from 'NSProxy' so that to forward requests
2633*67e74705SXin Li     // from one object to another.
2634*67e74705SXin Li     // Under such conditions, which means that every method possible is
2635*67e74705SXin Li     // implemented in the class, we should not issue "Method definition not
2636*67e74705SXin Li     // found" warnings.
2637*67e74705SXin Li     // FIXME: Use a general GetUnarySelector method for this.
2638*67e74705SXin Li     IdentifierInfo* II = &S.Context.Idents.get("forwardInvocation");
2639*67e74705SXin Li     Selector fISelector = S.Context.Selectors.getSelector(1, &II);
2640*67e74705SXin Li     if (InsMap.count(fISelector))
2641*67e74705SXin Li       // Is IDecl derived from 'NSProxy'? If so, no instance methods
2642*67e74705SXin Li       // need be implemented in the implementation.
2643*67e74705SXin Li       NSIDecl = IDecl->lookupInheritedClass(&S.Context.Idents.get("NSProxy"));
2644*67e74705SXin Li   }
2645*67e74705SXin Li 
2646*67e74705SXin Li   // If this is a forward protocol declaration, get its definition.
2647*67e74705SXin Li   if (!PDecl->isThisDeclarationADefinition() &&
2648*67e74705SXin Li       PDecl->getDefinition())
2649*67e74705SXin Li     PDecl = PDecl->getDefinition();
2650*67e74705SXin Li 
2651*67e74705SXin Li   // If a method lookup fails locally we still need to look and see if
2652*67e74705SXin Li   // the method was implemented by a base class or an inherited
2653*67e74705SXin Li   // protocol. This lookup is slow, but occurs rarely in correct code
2654*67e74705SXin Li   // and otherwise would terminate in a warning.
2655*67e74705SXin Li 
2656*67e74705SXin Li   // check unimplemented instance methods.
2657*67e74705SXin Li   if (!NSIDecl)
2658*67e74705SXin Li     for (auto *method : PDecl->instance_methods()) {
2659*67e74705SXin Li       if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
2660*67e74705SXin Li           !method->isPropertyAccessor() &&
2661*67e74705SXin Li           !InsMap.count(method->getSelector()) &&
2662*67e74705SXin Li           (!Super || !Super->lookupMethod(method->getSelector(),
2663*67e74705SXin Li                                           true /* instance */,
2664*67e74705SXin Li                                           false /* shallowCategory */,
2665*67e74705SXin Li                                           true /* followsSuper */,
2666*67e74705SXin Li                                           nullptr /* category */))) {
2667*67e74705SXin Li             // If a method is not implemented in the category implementation but
2668*67e74705SXin Li             // has been declared in its primary class, superclass,
2669*67e74705SXin Li             // or in one of their protocols, no need to issue the warning.
2670*67e74705SXin Li             // This is because method will be implemented in the primary class
2671*67e74705SXin Li             // or one of its super class implementation.
2672*67e74705SXin Li 
2673*67e74705SXin Li             // Ugly, but necessary. Method declared in protcol might have
2674*67e74705SXin Li             // have been synthesized due to a property declared in the class which
2675*67e74705SXin Li             // uses the protocol.
2676*67e74705SXin Li             if (ObjCMethodDecl *MethodInClass =
2677*67e74705SXin Li                   IDecl->lookupMethod(method->getSelector(),
2678*67e74705SXin Li                                       true /* instance */,
2679*67e74705SXin Li                                       true /* shallowCategoryLookup */,
2680*67e74705SXin Li                                       false /* followSuper */))
2681*67e74705SXin Li               if (C || MethodInClass->isPropertyAccessor())
2682*67e74705SXin Li                 continue;
2683*67e74705SXin Li             unsigned DIAG = diag::warn_unimplemented_protocol_method;
2684*67e74705SXin Li             if (!S.Diags.isIgnored(DIAG, ImpLoc)) {
2685*67e74705SXin Li               WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG,
2686*67e74705SXin Li                                   PDecl);
2687*67e74705SXin Li             }
2688*67e74705SXin Li           }
2689*67e74705SXin Li     }
2690*67e74705SXin Li   // check unimplemented class methods
2691*67e74705SXin Li   for (auto *method : PDecl->class_methods()) {
2692*67e74705SXin Li     if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
2693*67e74705SXin Li         !ClsMap.count(method->getSelector()) &&
2694*67e74705SXin Li         (!Super || !Super->lookupMethod(method->getSelector(),
2695*67e74705SXin Li                                         false /* class method */,
2696*67e74705SXin Li                                         false /* shallowCategoryLookup */,
2697*67e74705SXin Li                                         true  /* followSuper */,
2698*67e74705SXin Li                                         nullptr /* category */))) {
2699*67e74705SXin Li       // See above comment for instance method lookups.
2700*67e74705SXin Li       if (C && IDecl->lookupMethod(method->getSelector(),
2701*67e74705SXin Li                                    false /* class */,
2702*67e74705SXin Li                                    true /* shallowCategoryLookup */,
2703*67e74705SXin Li                                    false /* followSuper */))
2704*67e74705SXin Li         continue;
2705*67e74705SXin Li 
2706*67e74705SXin Li       unsigned DIAG = diag::warn_unimplemented_protocol_method;
2707*67e74705SXin Li       if (!S.Diags.isIgnored(DIAG, ImpLoc)) {
2708*67e74705SXin Li         WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, PDecl);
2709*67e74705SXin Li       }
2710*67e74705SXin Li     }
2711*67e74705SXin Li   }
2712*67e74705SXin Li   // Check on this protocols's referenced protocols, recursively.
2713*67e74705SXin Li   for (auto *PI : PDecl->protocols())
2714*67e74705SXin Li     CheckProtocolMethodDefs(S, ImpLoc, PI, IncompleteImpl, InsMap, ClsMap,
2715*67e74705SXin Li                             CDecl, ProtocolsExplictImpl);
2716*67e74705SXin Li }
2717*67e74705SXin Li 
2718*67e74705SXin Li /// MatchAllMethodDeclarations - Check methods declared in interface
2719*67e74705SXin Li /// or protocol against those declared in their implementations.
2720*67e74705SXin Li ///
MatchAllMethodDeclarations(const SelectorSet & InsMap,const SelectorSet & ClsMap,SelectorSet & InsMapSeen,SelectorSet & ClsMapSeen,ObjCImplDecl * IMPDecl,ObjCContainerDecl * CDecl,bool & IncompleteImpl,bool ImmediateClass,bool WarnCategoryMethodImpl)2721*67e74705SXin Li void Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap,
2722*67e74705SXin Li                                       const SelectorSet &ClsMap,
2723*67e74705SXin Li                                       SelectorSet &InsMapSeen,
2724*67e74705SXin Li                                       SelectorSet &ClsMapSeen,
2725*67e74705SXin Li                                       ObjCImplDecl* IMPDecl,
2726*67e74705SXin Li                                       ObjCContainerDecl* CDecl,
2727*67e74705SXin Li                                       bool &IncompleteImpl,
2728*67e74705SXin Li                                       bool ImmediateClass,
2729*67e74705SXin Li                                       bool WarnCategoryMethodImpl) {
2730*67e74705SXin Li   // Check and see if instance methods in class interface have been
2731*67e74705SXin Li   // implemented in the implementation class. If so, their types match.
2732*67e74705SXin Li   for (auto *I : CDecl->instance_methods()) {
2733*67e74705SXin Li     if (!InsMapSeen.insert(I->getSelector()).second)
2734*67e74705SXin Li       continue;
2735*67e74705SXin Li     if (!I->isPropertyAccessor() &&
2736*67e74705SXin Li         !InsMap.count(I->getSelector())) {
2737*67e74705SXin Li       if (ImmediateClass)
2738*67e74705SXin Li         WarnUndefinedMethod(*this, IMPDecl->getLocation(), I, IncompleteImpl,
2739*67e74705SXin Li                             diag::warn_undef_method_impl);
2740*67e74705SXin Li       continue;
2741*67e74705SXin Li     } else {
2742*67e74705SXin Li       ObjCMethodDecl *ImpMethodDecl =
2743*67e74705SXin Li         IMPDecl->getInstanceMethod(I->getSelector());
2744*67e74705SXin Li       assert(CDecl->getInstanceMethod(I->getSelector()) &&
2745*67e74705SXin Li              "Expected to find the method through lookup as well");
2746*67e74705SXin Li       // ImpMethodDecl may be null as in a @dynamic property.
2747*67e74705SXin Li       if (ImpMethodDecl) {
2748*67e74705SXin Li         if (!WarnCategoryMethodImpl)
2749*67e74705SXin Li           WarnConflictingTypedMethods(ImpMethodDecl, I,
2750*67e74705SXin Li                                       isa<ObjCProtocolDecl>(CDecl));
2751*67e74705SXin Li         else if (!I->isPropertyAccessor())
2752*67e74705SXin Li           WarnExactTypedMethods(ImpMethodDecl, I, isa<ObjCProtocolDecl>(CDecl));
2753*67e74705SXin Li       }
2754*67e74705SXin Li     }
2755*67e74705SXin Li   }
2756*67e74705SXin Li 
2757*67e74705SXin Li   // Check and see if class methods in class interface have been
2758*67e74705SXin Li   // implemented in the implementation class. If so, their types match.
2759*67e74705SXin Li   for (auto *I : CDecl->class_methods()) {
2760*67e74705SXin Li     if (!ClsMapSeen.insert(I->getSelector()).second)
2761*67e74705SXin Li       continue;
2762*67e74705SXin Li     if (!I->isPropertyAccessor() &&
2763*67e74705SXin Li         !ClsMap.count(I->getSelector())) {
2764*67e74705SXin Li       if (ImmediateClass)
2765*67e74705SXin Li         WarnUndefinedMethod(*this, IMPDecl->getLocation(), I, IncompleteImpl,
2766*67e74705SXin Li                             diag::warn_undef_method_impl);
2767*67e74705SXin Li     } else {
2768*67e74705SXin Li       ObjCMethodDecl *ImpMethodDecl =
2769*67e74705SXin Li         IMPDecl->getClassMethod(I->getSelector());
2770*67e74705SXin Li       assert(CDecl->getClassMethod(I->getSelector()) &&
2771*67e74705SXin Li              "Expected to find the method through lookup as well");
2772*67e74705SXin Li       // ImpMethodDecl may be null as in a @dynamic property.
2773*67e74705SXin Li       if (ImpMethodDecl) {
2774*67e74705SXin Li         if (!WarnCategoryMethodImpl)
2775*67e74705SXin Li           WarnConflictingTypedMethods(ImpMethodDecl, I,
2776*67e74705SXin Li                                       isa<ObjCProtocolDecl>(CDecl));
2777*67e74705SXin Li         else if (!I->isPropertyAccessor())
2778*67e74705SXin Li           WarnExactTypedMethods(ImpMethodDecl, I, isa<ObjCProtocolDecl>(CDecl));
2779*67e74705SXin Li       }
2780*67e74705SXin Li     }
2781*67e74705SXin Li   }
2782*67e74705SXin Li 
2783*67e74705SXin Li   if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl> (CDecl)) {
2784*67e74705SXin Li     // Also, check for methods declared in protocols inherited by
2785*67e74705SXin Li     // this protocol.
2786*67e74705SXin Li     for (auto *PI : PD->protocols())
2787*67e74705SXin Li       MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
2788*67e74705SXin Li                                  IMPDecl, PI, IncompleteImpl, false,
2789*67e74705SXin Li                                  WarnCategoryMethodImpl);
2790*67e74705SXin Li   }
2791*67e74705SXin Li 
2792*67e74705SXin Li   if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
2793*67e74705SXin Li     // when checking that methods in implementation match their declaration,
2794*67e74705SXin Li     // i.e. when WarnCategoryMethodImpl is false, check declarations in class
2795*67e74705SXin Li     // extension; as well as those in categories.
2796*67e74705SXin Li     if (!WarnCategoryMethodImpl) {
2797*67e74705SXin Li       for (auto *Cat : I->visible_categories())
2798*67e74705SXin Li         MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
2799*67e74705SXin Li                                    IMPDecl, Cat, IncompleteImpl,
2800*67e74705SXin Li                                    ImmediateClass && Cat->IsClassExtension(),
2801*67e74705SXin Li                                    WarnCategoryMethodImpl);
2802*67e74705SXin Li     } else {
2803*67e74705SXin Li       // Also methods in class extensions need be looked at next.
2804*67e74705SXin Li       for (auto *Ext : I->visible_extensions())
2805*67e74705SXin Li         MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
2806*67e74705SXin Li                                    IMPDecl, Ext, IncompleteImpl, false,
2807*67e74705SXin Li                                    WarnCategoryMethodImpl);
2808*67e74705SXin Li     }
2809*67e74705SXin Li 
2810*67e74705SXin Li     // Check for any implementation of a methods declared in protocol.
2811*67e74705SXin Li     for (auto *PI : I->all_referenced_protocols())
2812*67e74705SXin Li       MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
2813*67e74705SXin Li                                  IMPDecl, PI, IncompleteImpl, false,
2814*67e74705SXin Li                                  WarnCategoryMethodImpl);
2815*67e74705SXin Li 
2816*67e74705SXin Li     // FIXME. For now, we are not checking for extact match of methods
2817*67e74705SXin Li     // in category implementation and its primary class's super class.
2818*67e74705SXin Li     if (!WarnCategoryMethodImpl && I->getSuperClass())
2819*67e74705SXin Li       MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
2820*67e74705SXin Li                                  IMPDecl,
2821*67e74705SXin Li                                  I->getSuperClass(), IncompleteImpl, false);
2822*67e74705SXin Li   }
2823*67e74705SXin Li }
2824*67e74705SXin Li 
2825*67e74705SXin Li /// CheckCategoryVsClassMethodMatches - Checks that methods implemented in
2826*67e74705SXin Li /// category matches with those implemented in its primary class and
2827*67e74705SXin Li /// warns each time an exact match is found.
CheckCategoryVsClassMethodMatches(ObjCCategoryImplDecl * CatIMPDecl)2828*67e74705SXin Li void Sema::CheckCategoryVsClassMethodMatches(
2829*67e74705SXin Li                                   ObjCCategoryImplDecl *CatIMPDecl) {
2830*67e74705SXin Li   // Get category's primary class.
2831*67e74705SXin Li   ObjCCategoryDecl *CatDecl = CatIMPDecl->getCategoryDecl();
2832*67e74705SXin Li   if (!CatDecl)
2833*67e74705SXin Li     return;
2834*67e74705SXin Li   ObjCInterfaceDecl *IDecl = CatDecl->getClassInterface();
2835*67e74705SXin Li   if (!IDecl)
2836*67e74705SXin Li     return;
2837*67e74705SXin Li   ObjCInterfaceDecl *SuperIDecl = IDecl->getSuperClass();
2838*67e74705SXin Li   SelectorSet InsMap, ClsMap;
2839*67e74705SXin Li 
2840*67e74705SXin Li   for (const auto *I : CatIMPDecl->instance_methods()) {
2841*67e74705SXin Li     Selector Sel = I->getSelector();
2842*67e74705SXin Li     // When checking for methods implemented in the category, skip over
2843*67e74705SXin Li     // those declared in category class's super class. This is because
2844*67e74705SXin Li     // the super class must implement the method.
2845*67e74705SXin Li     if (SuperIDecl && SuperIDecl->lookupMethod(Sel, true))
2846*67e74705SXin Li       continue;
2847*67e74705SXin Li     InsMap.insert(Sel);
2848*67e74705SXin Li   }
2849*67e74705SXin Li 
2850*67e74705SXin Li   for (const auto *I : CatIMPDecl->class_methods()) {
2851*67e74705SXin Li     Selector Sel = I->getSelector();
2852*67e74705SXin Li     if (SuperIDecl && SuperIDecl->lookupMethod(Sel, false))
2853*67e74705SXin Li       continue;
2854*67e74705SXin Li     ClsMap.insert(Sel);
2855*67e74705SXin Li   }
2856*67e74705SXin Li   if (InsMap.empty() && ClsMap.empty())
2857*67e74705SXin Li     return;
2858*67e74705SXin Li 
2859*67e74705SXin Li   SelectorSet InsMapSeen, ClsMapSeen;
2860*67e74705SXin Li   bool IncompleteImpl = false;
2861*67e74705SXin Li   MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
2862*67e74705SXin Li                              CatIMPDecl, IDecl,
2863*67e74705SXin Li                              IncompleteImpl, false,
2864*67e74705SXin Li                              true /*WarnCategoryMethodImpl*/);
2865*67e74705SXin Li }
2866*67e74705SXin Li 
ImplMethodsVsClassMethods(Scope * S,ObjCImplDecl * IMPDecl,ObjCContainerDecl * CDecl,bool IncompleteImpl)2867*67e74705SXin Li void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
2868*67e74705SXin Li                                      ObjCContainerDecl* CDecl,
2869*67e74705SXin Li                                      bool IncompleteImpl) {
2870*67e74705SXin Li   SelectorSet InsMap;
2871*67e74705SXin Li   // Check and see if instance methods in class interface have been
2872*67e74705SXin Li   // implemented in the implementation class.
2873*67e74705SXin Li   for (const auto *I : IMPDecl->instance_methods())
2874*67e74705SXin Li     InsMap.insert(I->getSelector());
2875*67e74705SXin Li 
2876*67e74705SXin Li   // Add the selectors for getters/setters of @dynamic properties.
2877*67e74705SXin Li   for (const auto *PImpl : IMPDecl->property_impls()) {
2878*67e74705SXin Li     // We only care about @dynamic implementations.
2879*67e74705SXin Li     if (PImpl->getPropertyImplementation() != ObjCPropertyImplDecl::Dynamic)
2880*67e74705SXin Li       continue;
2881*67e74705SXin Li 
2882*67e74705SXin Li     const auto *P = PImpl->getPropertyDecl();
2883*67e74705SXin Li     if (!P) continue;
2884*67e74705SXin Li 
2885*67e74705SXin Li     InsMap.insert(P->getGetterName());
2886*67e74705SXin Li     if (!P->getSetterName().isNull())
2887*67e74705SXin Li       InsMap.insert(P->getSetterName());
2888*67e74705SXin Li   }
2889*67e74705SXin Li 
2890*67e74705SXin Li   // Check and see if properties declared in the interface have either 1)
2891*67e74705SXin Li   // an implementation or 2) there is a @synthesize/@dynamic implementation
2892*67e74705SXin Li   // of the property in the @implementation.
2893*67e74705SXin Li   if (const ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
2894*67e74705SXin Li     bool SynthesizeProperties = LangOpts.ObjCDefaultSynthProperties &&
2895*67e74705SXin Li                                 LangOpts.ObjCRuntime.isNonFragile() &&
2896*67e74705SXin Li                                 !IDecl->isObjCRequiresPropertyDefs();
2897*67e74705SXin Li     DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, SynthesizeProperties);
2898*67e74705SXin Li   }
2899*67e74705SXin Li 
2900*67e74705SXin Li   // Diagnose null-resettable synthesized setters.
2901*67e74705SXin Li   diagnoseNullResettableSynthesizedSetters(IMPDecl);
2902*67e74705SXin Li 
2903*67e74705SXin Li   SelectorSet ClsMap;
2904*67e74705SXin Li   for (const auto *I : IMPDecl->class_methods())
2905*67e74705SXin Li     ClsMap.insert(I->getSelector());
2906*67e74705SXin Li 
2907*67e74705SXin Li   // Check for type conflict of methods declared in a class/protocol and
2908*67e74705SXin Li   // its implementation; if any.
2909*67e74705SXin Li   SelectorSet InsMapSeen, ClsMapSeen;
2910*67e74705SXin Li   MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
2911*67e74705SXin Li                              IMPDecl, CDecl,
2912*67e74705SXin Li                              IncompleteImpl, true);
2913*67e74705SXin Li 
2914*67e74705SXin Li   // check all methods implemented in category against those declared
2915*67e74705SXin Li   // in its primary class.
2916*67e74705SXin Li   if (ObjCCategoryImplDecl *CatDecl =
2917*67e74705SXin Li         dyn_cast<ObjCCategoryImplDecl>(IMPDecl))
2918*67e74705SXin Li     CheckCategoryVsClassMethodMatches(CatDecl);
2919*67e74705SXin Li 
2920*67e74705SXin Li   // Check the protocol list for unimplemented methods in the @implementation
2921*67e74705SXin Li   // class.
2922*67e74705SXin Li   // Check and see if class methods in class interface have been
2923*67e74705SXin Li   // implemented in the implementation class.
2924*67e74705SXin Li 
2925*67e74705SXin Li   LazyProtocolNameSet ExplicitImplProtocols;
2926*67e74705SXin Li 
2927*67e74705SXin Li   if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
2928*67e74705SXin Li     for (auto *PI : I->all_referenced_protocols())
2929*67e74705SXin Li       CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), PI, IncompleteImpl,
2930*67e74705SXin Li                               InsMap, ClsMap, I, ExplicitImplProtocols);
2931*67e74705SXin Li   } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
2932*67e74705SXin Li     // For extended class, unimplemented methods in its protocols will
2933*67e74705SXin Li     // be reported in the primary class.
2934*67e74705SXin Li     if (!C->IsClassExtension()) {
2935*67e74705SXin Li       for (auto *P : C->protocols())
2936*67e74705SXin Li         CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), P,
2937*67e74705SXin Li                                 IncompleteImpl, InsMap, ClsMap, CDecl,
2938*67e74705SXin Li                                 ExplicitImplProtocols);
2939*67e74705SXin Li       DiagnoseUnimplementedProperties(S, IMPDecl, CDecl,
2940*67e74705SXin Li                                       /*SynthesizeProperties=*/false);
2941*67e74705SXin Li     }
2942*67e74705SXin Li   } else
2943*67e74705SXin Li     llvm_unreachable("invalid ObjCContainerDecl type.");
2944*67e74705SXin Li }
2945*67e74705SXin Li 
2946*67e74705SXin Li Sema::DeclGroupPtrTy
ActOnForwardClassDeclaration(SourceLocation AtClassLoc,IdentifierInfo ** IdentList,SourceLocation * IdentLocs,ArrayRef<ObjCTypeParamList * > TypeParamLists,unsigned NumElts)2947*67e74705SXin Li Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
2948*67e74705SXin Li                                    IdentifierInfo **IdentList,
2949*67e74705SXin Li                                    SourceLocation *IdentLocs,
2950*67e74705SXin Li                                    ArrayRef<ObjCTypeParamList *> TypeParamLists,
2951*67e74705SXin Li                                    unsigned NumElts) {
2952*67e74705SXin Li   SmallVector<Decl *, 8> DeclsInGroup;
2953*67e74705SXin Li   for (unsigned i = 0; i != NumElts; ++i) {
2954*67e74705SXin Li     // Check for another declaration kind with the same name.
2955*67e74705SXin Li     NamedDecl *PrevDecl
2956*67e74705SXin Li       = LookupSingleName(TUScope, IdentList[i], IdentLocs[i],
2957*67e74705SXin Li                          LookupOrdinaryName, ForRedeclaration);
2958*67e74705SXin Li     if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
2959*67e74705SXin Li       // GCC apparently allows the following idiom:
2960*67e74705SXin Li       //
2961*67e74705SXin Li       // typedef NSObject < XCElementTogglerP > XCElementToggler;
2962*67e74705SXin Li       // @class XCElementToggler;
2963*67e74705SXin Li       //
2964*67e74705SXin Li       // Here we have chosen to ignore the forward class declaration
2965*67e74705SXin Li       // with a warning. Since this is the implied behavior.
2966*67e74705SXin Li       TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(PrevDecl);
2967*67e74705SXin Li       if (!TDD || !TDD->getUnderlyingType()->isObjCObjectType()) {
2968*67e74705SXin Li         Diag(AtClassLoc, diag::err_redefinition_different_kind) << IdentList[i];
2969*67e74705SXin Li         Diag(PrevDecl->getLocation(), diag::note_previous_definition);
2970*67e74705SXin Li       } else {
2971*67e74705SXin Li         // a forward class declaration matching a typedef name of a class refers
2972*67e74705SXin Li         // to the underlying class. Just ignore the forward class with a warning
2973*67e74705SXin Li         // as this will force the intended behavior which is to lookup the
2974*67e74705SXin Li         // typedef name.
2975*67e74705SXin Li         if (isa<ObjCObjectType>(TDD->getUnderlyingType())) {
2976*67e74705SXin Li           Diag(AtClassLoc, diag::warn_forward_class_redefinition)
2977*67e74705SXin Li               << IdentList[i];
2978*67e74705SXin Li           Diag(PrevDecl->getLocation(), diag::note_previous_definition);
2979*67e74705SXin Li           continue;
2980*67e74705SXin Li         }
2981*67e74705SXin Li       }
2982*67e74705SXin Li     }
2983*67e74705SXin Li 
2984*67e74705SXin Li     // Create a declaration to describe this forward declaration.
2985*67e74705SXin Li     ObjCInterfaceDecl *PrevIDecl
2986*67e74705SXin Li       = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
2987*67e74705SXin Li 
2988*67e74705SXin Li     IdentifierInfo *ClassName = IdentList[i];
2989*67e74705SXin Li     if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) {
2990*67e74705SXin Li       // A previous decl with a different name is because of
2991*67e74705SXin Li       // @compatibility_alias, for example:
2992*67e74705SXin Li       // \code
2993*67e74705SXin Li       //   @class NewImage;
2994*67e74705SXin Li       //   @compatibility_alias OldImage NewImage;
2995*67e74705SXin Li       // \endcode
2996*67e74705SXin Li       // A lookup for 'OldImage' will return the 'NewImage' decl.
2997*67e74705SXin Li       //
2998*67e74705SXin Li       // In such a case use the real declaration name, instead of the alias one,
2999*67e74705SXin Li       // otherwise we will break IdentifierResolver and redecls-chain invariants.
3000*67e74705SXin Li       // FIXME: If necessary, add a bit to indicate that this ObjCInterfaceDecl
3001*67e74705SXin Li       // has been aliased.
3002*67e74705SXin Li       ClassName = PrevIDecl->getIdentifier();
3003*67e74705SXin Li     }
3004*67e74705SXin Li 
3005*67e74705SXin Li     // If this forward declaration has type parameters, compare them with the
3006*67e74705SXin Li     // type parameters of the previous declaration.
3007*67e74705SXin Li     ObjCTypeParamList *TypeParams = TypeParamLists[i];
3008*67e74705SXin Li     if (PrevIDecl && TypeParams) {
3009*67e74705SXin Li       if (ObjCTypeParamList *PrevTypeParams = PrevIDecl->getTypeParamList()) {
3010*67e74705SXin Li         // Check for consistency with the previous declaration.
3011*67e74705SXin Li         if (checkTypeParamListConsistency(
3012*67e74705SXin Li               *this, PrevTypeParams, TypeParams,
3013*67e74705SXin Li               TypeParamListContext::ForwardDeclaration)) {
3014*67e74705SXin Li           TypeParams = nullptr;
3015*67e74705SXin Li         }
3016*67e74705SXin Li       } else if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) {
3017*67e74705SXin Li         // The @interface does not have type parameters. Complain.
3018*67e74705SXin Li         Diag(IdentLocs[i], diag::err_objc_parameterized_forward_class)
3019*67e74705SXin Li           << ClassName
3020*67e74705SXin Li           << TypeParams->getSourceRange();
3021*67e74705SXin Li         Diag(Def->getLocation(), diag::note_defined_here)
3022*67e74705SXin Li           << ClassName;
3023*67e74705SXin Li 
3024*67e74705SXin Li         TypeParams = nullptr;
3025*67e74705SXin Li       }
3026*67e74705SXin Li     }
3027*67e74705SXin Li 
3028*67e74705SXin Li     ObjCInterfaceDecl *IDecl
3029*67e74705SXin Li       = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
3030*67e74705SXin Li                                   ClassName, TypeParams, PrevIDecl,
3031*67e74705SXin Li                                   IdentLocs[i]);
3032*67e74705SXin Li     IDecl->setAtEndRange(IdentLocs[i]);
3033*67e74705SXin Li 
3034*67e74705SXin Li     PushOnScopeChains(IDecl, TUScope);
3035*67e74705SXin Li     CheckObjCDeclScope(IDecl);
3036*67e74705SXin Li     DeclsInGroup.push_back(IDecl);
3037*67e74705SXin Li   }
3038*67e74705SXin Li 
3039*67e74705SXin Li   return BuildDeclaratorGroup(DeclsInGroup, false);
3040*67e74705SXin Li }
3041*67e74705SXin Li 
3042*67e74705SXin Li static bool tryMatchRecordTypes(ASTContext &Context,
3043*67e74705SXin Li                                 Sema::MethodMatchStrategy strategy,
3044*67e74705SXin Li                                 const Type *left, const Type *right);
3045*67e74705SXin Li 
matchTypes(ASTContext & Context,Sema::MethodMatchStrategy strategy,QualType leftQT,QualType rightQT)3046*67e74705SXin Li static bool matchTypes(ASTContext &Context, Sema::MethodMatchStrategy strategy,
3047*67e74705SXin Li                        QualType leftQT, QualType rightQT) {
3048*67e74705SXin Li   const Type *left =
3049*67e74705SXin Li     Context.getCanonicalType(leftQT).getUnqualifiedType().getTypePtr();
3050*67e74705SXin Li   const Type *right =
3051*67e74705SXin Li     Context.getCanonicalType(rightQT).getUnqualifiedType().getTypePtr();
3052*67e74705SXin Li 
3053*67e74705SXin Li   if (left == right) return true;
3054*67e74705SXin Li 
3055*67e74705SXin Li   // If we're doing a strict match, the types have to match exactly.
3056*67e74705SXin Li   if (strategy == Sema::MMS_strict) return false;
3057*67e74705SXin Li 
3058*67e74705SXin Li   if (left->isIncompleteType() || right->isIncompleteType()) return false;
3059*67e74705SXin Li 
3060*67e74705SXin Li   // Otherwise, use this absurdly complicated algorithm to try to
3061*67e74705SXin Li   // validate the basic, low-level compatibility of the two types.
3062*67e74705SXin Li 
3063*67e74705SXin Li   // As a minimum, require the sizes and alignments to match.
3064*67e74705SXin Li   TypeInfo LeftTI = Context.getTypeInfo(left);
3065*67e74705SXin Li   TypeInfo RightTI = Context.getTypeInfo(right);
3066*67e74705SXin Li   if (LeftTI.Width != RightTI.Width)
3067*67e74705SXin Li     return false;
3068*67e74705SXin Li 
3069*67e74705SXin Li   if (LeftTI.Align != RightTI.Align)
3070*67e74705SXin Li     return false;
3071*67e74705SXin Li 
3072*67e74705SXin Li   // Consider all the kinds of non-dependent canonical types:
3073*67e74705SXin Li   // - functions and arrays aren't possible as return and parameter types
3074*67e74705SXin Li 
3075*67e74705SXin Li   // - vector types of equal size can be arbitrarily mixed
3076*67e74705SXin Li   if (isa<VectorType>(left)) return isa<VectorType>(right);
3077*67e74705SXin Li   if (isa<VectorType>(right)) return false;
3078*67e74705SXin Li 
3079*67e74705SXin Li   // - references should only match references of identical type
3080*67e74705SXin Li   // - structs, unions, and Objective-C objects must match more-or-less
3081*67e74705SXin Li   //   exactly
3082*67e74705SXin Li   // - everything else should be a scalar
3083*67e74705SXin Li   if (!left->isScalarType() || !right->isScalarType())
3084*67e74705SXin Li     return tryMatchRecordTypes(Context, strategy, left, right);
3085*67e74705SXin Li 
3086*67e74705SXin Li   // Make scalars agree in kind, except count bools as chars, and group
3087*67e74705SXin Li   // all non-member pointers together.
3088*67e74705SXin Li   Type::ScalarTypeKind leftSK = left->getScalarTypeKind();
3089*67e74705SXin Li   Type::ScalarTypeKind rightSK = right->getScalarTypeKind();
3090*67e74705SXin Li   if (leftSK == Type::STK_Bool) leftSK = Type::STK_Integral;
3091*67e74705SXin Li   if (rightSK == Type::STK_Bool) rightSK = Type::STK_Integral;
3092*67e74705SXin Li   if (leftSK == Type::STK_CPointer || leftSK == Type::STK_BlockPointer)
3093*67e74705SXin Li     leftSK = Type::STK_ObjCObjectPointer;
3094*67e74705SXin Li   if (rightSK == Type::STK_CPointer || rightSK == Type::STK_BlockPointer)
3095*67e74705SXin Li     rightSK = Type::STK_ObjCObjectPointer;
3096*67e74705SXin Li 
3097*67e74705SXin Li   // Note that data member pointers and function member pointers don't
3098*67e74705SXin Li   // intermix because of the size differences.
3099*67e74705SXin Li 
3100*67e74705SXin Li   return (leftSK == rightSK);
3101*67e74705SXin Li }
3102*67e74705SXin Li 
tryMatchRecordTypes(ASTContext & Context,Sema::MethodMatchStrategy strategy,const Type * lt,const Type * rt)3103*67e74705SXin Li static bool tryMatchRecordTypes(ASTContext &Context,
3104*67e74705SXin Li                                 Sema::MethodMatchStrategy strategy,
3105*67e74705SXin Li                                 const Type *lt, const Type *rt) {
3106*67e74705SXin Li   assert(lt && rt && lt != rt);
3107*67e74705SXin Li 
3108*67e74705SXin Li   if (!isa<RecordType>(lt) || !isa<RecordType>(rt)) return false;
3109*67e74705SXin Li   RecordDecl *left = cast<RecordType>(lt)->getDecl();
3110*67e74705SXin Li   RecordDecl *right = cast<RecordType>(rt)->getDecl();
3111*67e74705SXin Li 
3112*67e74705SXin Li   // Require union-hood to match.
3113*67e74705SXin Li   if (left->isUnion() != right->isUnion()) return false;
3114*67e74705SXin Li 
3115*67e74705SXin Li   // Require an exact match if either is non-POD.
3116*67e74705SXin Li   if ((isa<CXXRecordDecl>(left) && !cast<CXXRecordDecl>(left)->isPOD()) ||
3117*67e74705SXin Li       (isa<CXXRecordDecl>(right) && !cast<CXXRecordDecl>(right)->isPOD()))
3118*67e74705SXin Li     return false;
3119*67e74705SXin Li 
3120*67e74705SXin Li   // Require size and alignment to match.
3121*67e74705SXin Li   TypeInfo LeftTI = Context.getTypeInfo(lt);
3122*67e74705SXin Li   TypeInfo RightTI = Context.getTypeInfo(rt);
3123*67e74705SXin Li   if (LeftTI.Width != RightTI.Width)
3124*67e74705SXin Li     return false;
3125*67e74705SXin Li 
3126*67e74705SXin Li   if (LeftTI.Align != RightTI.Align)
3127*67e74705SXin Li     return false;
3128*67e74705SXin Li 
3129*67e74705SXin Li   // Require fields to match.
3130*67e74705SXin Li   RecordDecl::field_iterator li = left->field_begin(), le = left->field_end();
3131*67e74705SXin Li   RecordDecl::field_iterator ri = right->field_begin(), re = right->field_end();
3132*67e74705SXin Li   for (; li != le && ri != re; ++li, ++ri) {
3133*67e74705SXin Li     if (!matchTypes(Context, strategy, li->getType(), ri->getType()))
3134*67e74705SXin Li       return false;
3135*67e74705SXin Li   }
3136*67e74705SXin Li   return (li == le && ri == re);
3137*67e74705SXin Li }
3138*67e74705SXin Li 
3139*67e74705SXin Li /// MatchTwoMethodDeclarations - Checks that two methods have matching type and
3140*67e74705SXin Li /// returns true, or false, accordingly.
3141*67e74705SXin Li /// TODO: Handle protocol list; such as id<p1,p2> in type comparisons
MatchTwoMethodDeclarations(const ObjCMethodDecl * left,const ObjCMethodDecl * right,MethodMatchStrategy strategy)3142*67e74705SXin Li bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *left,
3143*67e74705SXin Li                                       const ObjCMethodDecl *right,
3144*67e74705SXin Li                                       MethodMatchStrategy strategy) {
3145*67e74705SXin Li   if (!matchTypes(Context, strategy, left->getReturnType(),
3146*67e74705SXin Li                   right->getReturnType()))
3147*67e74705SXin Li     return false;
3148*67e74705SXin Li 
3149*67e74705SXin Li   // If either is hidden, it is not considered to match.
3150*67e74705SXin Li   if (left->isHidden() || right->isHidden())
3151*67e74705SXin Li     return false;
3152*67e74705SXin Li 
3153*67e74705SXin Li   if (getLangOpts().ObjCAutoRefCount &&
3154*67e74705SXin Li       (left->hasAttr<NSReturnsRetainedAttr>()
3155*67e74705SXin Li          != right->hasAttr<NSReturnsRetainedAttr>() ||
3156*67e74705SXin Li        left->hasAttr<NSConsumesSelfAttr>()
3157*67e74705SXin Li          != right->hasAttr<NSConsumesSelfAttr>()))
3158*67e74705SXin Li     return false;
3159*67e74705SXin Li 
3160*67e74705SXin Li   ObjCMethodDecl::param_const_iterator
3161*67e74705SXin Li     li = left->param_begin(), le = left->param_end(), ri = right->param_begin(),
3162*67e74705SXin Li     re = right->param_end();
3163*67e74705SXin Li 
3164*67e74705SXin Li   for (; li != le && ri != re; ++li, ++ri) {
3165*67e74705SXin Li     assert(ri != right->param_end() && "Param mismatch");
3166*67e74705SXin Li     const ParmVarDecl *lparm = *li, *rparm = *ri;
3167*67e74705SXin Li 
3168*67e74705SXin Li     if (!matchTypes(Context, strategy, lparm->getType(), rparm->getType()))
3169*67e74705SXin Li       return false;
3170*67e74705SXin Li 
3171*67e74705SXin Li     if (getLangOpts().ObjCAutoRefCount &&
3172*67e74705SXin Li         lparm->hasAttr<NSConsumedAttr>() != rparm->hasAttr<NSConsumedAttr>())
3173*67e74705SXin Li       return false;
3174*67e74705SXin Li   }
3175*67e74705SXin Li   return true;
3176*67e74705SXin Li }
3177*67e74705SXin Li 
isMethodContextSameForKindofLookup(ObjCMethodDecl * Method,ObjCMethodDecl * MethodInList)3178*67e74705SXin Li static bool isMethodContextSameForKindofLookup(ObjCMethodDecl *Method,
3179*67e74705SXin Li                                                ObjCMethodDecl *MethodInList) {
3180*67e74705SXin Li   auto *MethodProtocol = dyn_cast<ObjCProtocolDecl>(Method->getDeclContext());
3181*67e74705SXin Li   auto *MethodInListProtocol =
3182*67e74705SXin Li       dyn_cast<ObjCProtocolDecl>(MethodInList->getDeclContext());
3183*67e74705SXin Li   // If this method belongs to a protocol but the method in list does not, or
3184*67e74705SXin Li   // vice versa, we say the context is not the same.
3185*67e74705SXin Li   if ((MethodProtocol && !MethodInListProtocol) ||
3186*67e74705SXin Li       (!MethodProtocol && MethodInListProtocol))
3187*67e74705SXin Li     return false;
3188*67e74705SXin Li 
3189*67e74705SXin Li   if (MethodProtocol && MethodInListProtocol)
3190*67e74705SXin Li     return true;
3191*67e74705SXin Li 
3192*67e74705SXin Li   ObjCInterfaceDecl *MethodInterface = Method->getClassInterface();
3193*67e74705SXin Li   ObjCInterfaceDecl *MethodInListInterface =
3194*67e74705SXin Li       MethodInList->getClassInterface();
3195*67e74705SXin Li   return MethodInterface == MethodInListInterface;
3196*67e74705SXin Li }
3197*67e74705SXin Li 
addMethodToGlobalList(ObjCMethodList * List,ObjCMethodDecl * Method)3198*67e74705SXin Li void Sema::addMethodToGlobalList(ObjCMethodList *List,
3199*67e74705SXin Li                                  ObjCMethodDecl *Method) {
3200*67e74705SXin Li   // Record at the head of the list whether there were 0, 1, or >= 2 methods
3201*67e74705SXin Li   // inside categories.
3202*67e74705SXin Li   if (ObjCCategoryDecl *CD =
3203*67e74705SXin Li           dyn_cast<ObjCCategoryDecl>(Method->getDeclContext()))
3204*67e74705SXin Li     if (!CD->IsClassExtension() && List->getBits() < 2)
3205*67e74705SXin Li       List->setBits(List->getBits() + 1);
3206*67e74705SXin Li 
3207*67e74705SXin Li   // If the list is empty, make it a singleton list.
3208*67e74705SXin Li   if (List->getMethod() == nullptr) {
3209*67e74705SXin Li     List->setMethod(Method);
3210*67e74705SXin Li     List->setNext(nullptr);
3211*67e74705SXin Li     return;
3212*67e74705SXin Li   }
3213*67e74705SXin Li 
3214*67e74705SXin Li   // We've seen a method with this name, see if we have already seen this type
3215*67e74705SXin Li   // signature.
3216*67e74705SXin Li   ObjCMethodList *Previous = List;
3217*67e74705SXin Li   ObjCMethodList *ListWithSameDeclaration = nullptr;
3218*67e74705SXin Li   for (; List; Previous = List, List = List->getNext()) {
3219*67e74705SXin Li     // If we are building a module, keep all of the methods.
3220*67e74705SXin Li     if (getLangOpts().CompilingModule)
3221*67e74705SXin Li       continue;
3222*67e74705SXin Li 
3223*67e74705SXin Li     bool SameDeclaration = MatchTwoMethodDeclarations(Method,
3224*67e74705SXin Li                                                       List->getMethod());
3225*67e74705SXin Li     // Looking for method with a type bound requires the correct context exists.
3226*67e74705SXin Li     // We need to insert a method into the list if the context is different.
3227*67e74705SXin Li     // If the method's declaration matches the list
3228*67e74705SXin Li     // a> the method belongs to a different context: we need to insert it, in
3229*67e74705SXin Li     //    order to emit the availability message, we need to prioritize over
3230*67e74705SXin Li     //    availability among the methods with the same declaration.
3231*67e74705SXin Li     // b> the method belongs to the same context: there is no need to insert a
3232*67e74705SXin Li     //    new entry.
3233*67e74705SXin Li     // If the method's declaration does not match the list, we insert it to the
3234*67e74705SXin Li     // end.
3235*67e74705SXin Li     if (!SameDeclaration ||
3236*67e74705SXin Li         !isMethodContextSameForKindofLookup(Method, List->getMethod())) {
3237*67e74705SXin Li       // Even if two method types do not match, we would like to say
3238*67e74705SXin Li       // there is more than one declaration so unavailability/deprecated
3239*67e74705SXin Li       // warning is not too noisy.
3240*67e74705SXin Li       if (!Method->isDefined())
3241*67e74705SXin Li         List->setHasMoreThanOneDecl(true);
3242*67e74705SXin Li 
3243*67e74705SXin Li       // For methods with the same declaration, the one that is deprecated
3244*67e74705SXin Li       // should be put in the front for better diagnostics.
3245*67e74705SXin Li       if (Method->isDeprecated() && SameDeclaration &&
3246*67e74705SXin Li           !ListWithSameDeclaration && !List->getMethod()->isDeprecated())
3247*67e74705SXin Li         ListWithSameDeclaration = List;
3248*67e74705SXin Li 
3249*67e74705SXin Li       if (Method->isUnavailable() && SameDeclaration &&
3250*67e74705SXin Li           !ListWithSameDeclaration &&
3251*67e74705SXin Li           List->getMethod()->getAvailability() < AR_Deprecated)
3252*67e74705SXin Li         ListWithSameDeclaration = List;
3253*67e74705SXin Li       continue;
3254*67e74705SXin Li     }
3255*67e74705SXin Li 
3256*67e74705SXin Li     ObjCMethodDecl *PrevObjCMethod = List->getMethod();
3257*67e74705SXin Li 
3258*67e74705SXin Li     // Propagate the 'defined' bit.
3259*67e74705SXin Li     if (Method->isDefined())
3260*67e74705SXin Li       PrevObjCMethod->setDefined(true);
3261*67e74705SXin Li     else {
3262*67e74705SXin Li       // Objective-C doesn't allow an @interface for a class after its
3263*67e74705SXin Li       // @implementation. So if Method is not defined and there already is
3264*67e74705SXin Li       // an entry for this type signature, Method has to be for a different
3265*67e74705SXin Li       // class than PrevObjCMethod.
3266*67e74705SXin Li       List->setHasMoreThanOneDecl(true);
3267*67e74705SXin Li     }
3268*67e74705SXin Li 
3269*67e74705SXin Li     // If a method is deprecated, push it in the global pool.
3270*67e74705SXin Li     // This is used for better diagnostics.
3271*67e74705SXin Li     if (Method->isDeprecated()) {
3272*67e74705SXin Li       if (!PrevObjCMethod->isDeprecated())
3273*67e74705SXin Li         List->setMethod(Method);
3274*67e74705SXin Li     }
3275*67e74705SXin Li     // If the new method is unavailable, push it into global pool
3276*67e74705SXin Li     // unless previous one is deprecated.
3277*67e74705SXin Li     if (Method->isUnavailable()) {
3278*67e74705SXin Li       if (PrevObjCMethod->getAvailability() < AR_Deprecated)
3279*67e74705SXin Li         List->setMethod(Method);
3280*67e74705SXin Li     }
3281*67e74705SXin Li 
3282*67e74705SXin Li     return;
3283*67e74705SXin Li   }
3284*67e74705SXin Li 
3285*67e74705SXin Li   // We have a new signature for an existing method - add it.
3286*67e74705SXin Li   // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
3287*67e74705SXin Li   ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>();
3288*67e74705SXin Li 
3289*67e74705SXin Li   // We insert it right before ListWithSameDeclaration.
3290*67e74705SXin Li   if (ListWithSameDeclaration) {
3291*67e74705SXin Li     auto *List = new (Mem) ObjCMethodList(*ListWithSameDeclaration);
3292*67e74705SXin Li     // FIXME: should we clear the other bits in ListWithSameDeclaration?
3293*67e74705SXin Li     ListWithSameDeclaration->setMethod(Method);
3294*67e74705SXin Li     ListWithSameDeclaration->setNext(List);
3295*67e74705SXin Li     return;
3296*67e74705SXin Li   }
3297*67e74705SXin Li 
3298*67e74705SXin Li   Previous->setNext(new (Mem) ObjCMethodList(Method));
3299*67e74705SXin Li }
3300*67e74705SXin Li 
3301*67e74705SXin Li /// \brief Read the contents of the method pool for a given selector from
3302*67e74705SXin Li /// external storage.
ReadMethodPool(Selector Sel)3303*67e74705SXin Li void Sema::ReadMethodPool(Selector Sel) {
3304*67e74705SXin Li   assert(ExternalSource && "We need an external AST source");
3305*67e74705SXin Li   ExternalSource->ReadMethodPool(Sel);
3306*67e74705SXin Li }
3307*67e74705SXin Li 
updateOutOfDateSelector(Selector Sel)3308*67e74705SXin Li void Sema::updateOutOfDateSelector(Selector Sel) {
3309*67e74705SXin Li   if (!ExternalSource)
3310*67e74705SXin Li     return;
3311*67e74705SXin Li   ExternalSource->updateOutOfDateSelector(Sel);
3312*67e74705SXin Li }
3313*67e74705SXin Li 
AddMethodToGlobalPool(ObjCMethodDecl * Method,bool impl,bool instance)3314*67e74705SXin Li void Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl,
3315*67e74705SXin Li                                  bool instance) {
3316*67e74705SXin Li   // Ignore methods of invalid containers.
3317*67e74705SXin Li   if (cast<Decl>(Method->getDeclContext())->isInvalidDecl())
3318*67e74705SXin Li     return;
3319*67e74705SXin Li 
3320*67e74705SXin Li   if (ExternalSource)
3321*67e74705SXin Li     ReadMethodPool(Method->getSelector());
3322*67e74705SXin Li 
3323*67e74705SXin Li   GlobalMethodPool::iterator Pos = MethodPool.find(Method->getSelector());
3324*67e74705SXin Li   if (Pos == MethodPool.end())
3325*67e74705SXin Li     Pos = MethodPool.insert(std::make_pair(Method->getSelector(),
3326*67e74705SXin Li                                            GlobalMethods())).first;
3327*67e74705SXin Li 
3328*67e74705SXin Li   Method->setDefined(impl);
3329*67e74705SXin Li 
3330*67e74705SXin Li   ObjCMethodList &Entry = instance ? Pos->second.first : Pos->second.second;
3331*67e74705SXin Li   addMethodToGlobalList(&Entry, Method);
3332*67e74705SXin Li }
3333*67e74705SXin Li 
3334*67e74705SXin Li /// Determines if this is an "acceptable" loose mismatch in the global
3335*67e74705SXin Li /// method pool.  This exists mostly as a hack to get around certain
3336*67e74705SXin Li /// global mismatches which we can't afford to make warnings / errors.
3337*67e74705SXin Li /// Really, what we want is a way to take a method out of the global
3338*67e74705SXin Li /// method pool.
isAcceptableMethodMismatch(ObjCMethodDecl * chosen,ObjCMethodDecl * other)3339*67e74705SXin Li static bool isAcceptableMethodMismatch(ObjCMethodDecl *chosen,
3340*67e74705SXin Li                                        ObjCMethodDecl *other) {
3341*67e74705SXin Li   if (!chosen->isInstanceMethod())
3342*67e74705SXin Li     return false;
3343*67e74705SXin Li 
3344*67e74705SXin Li   Selector sel = chosen->getSelector();
3345*67e74705SXin Li   if (!sel.isUnarySelector() || sel.getNameForSlot(0) != "length")
3346*67e74705SXin Li     return false;
3347*67e74705SXin Li 
3348*67e74705SXin Li   // Don't complain about mismatches for -length if the method we
3349*67e74705SXin Li   // chose has an integral result type.
3350*67e74705SXin Li   return (chosen->getReturnType()->isIntegerType());
3351*67e74705SXin Li }
3352*67e74705SXin Li 
3353*67e74705SXin Li /// Return true if the given method is wthin the type bound.
FilterMethodsByTypeBound(ObjCMethodDecl * Method,const ObjCObjectType * TypeBound)3354*67e74705SXin Li static bool FilterMethodsByTypeBound(ObjCMethodDecl *Method,
3355*67e74705SXin Li                                      const ObjCObjectType *TypeBound) {
3356*67e74705SXin Li   if (!TypeBound)
3357*67e74705SXin Li     return true;
3358*67e74705SXin Li 
3359*67e74705SXin Li   if (TypeBound->isObjCId())
3360*67e74705SXin Li     // FIXME: should we handle the case of bounding to id<A, B> differently?
3361*67e74705SXin Li     return true;
3362*67e74705SXin Li 
3363*67e74705SXin Li   auto *BoundInterface = TypeBound->getInterface();
3364*67e74705SXin Li   assert(BoundInterface && "unexpected object type!");
3365*67e74705SXin Li 
3366*67e74705SXin Li   // Check if the Method belongs to a protocol. We should allow any method
3367*67e74705SXin Li   // defined in any protocol, because any subclass could adopt the protocol.
3368*67e74705SXin Li   auto *MethodProtocol = dyn_cast<ObjCProtocolDecl>(Method->getDeclContext());
3369*67e74705SXin Li   if (MethodProtocol) {
3370*67e74705SXin Li     return true;
3371*67e74705SXin Li   }
3372*67e74705SXin Li 
3373*67e74705SXin Li   // If the Method belongs to a class, check if it belongs to the class
3374*67e74705SXin Li   // hierarchy of the class bound.
3375*67e74705SXin Li   if (ObjCInterfaceDecl *MethodInterface = Method->getClassInterface()) {
3376*67e74705SXin Li     // We allow methods declared within classes that are part of the hierarchy
3377*67e74705SXin Li     // of the class bound (superclass of, subclass of, or the same as the class
3378*67e74705SXin Li     // bound).
3379*67e74705SXin Li     return MethodInterface == BoundInterface ||
3380*67e74705SXin Li            MethodInterface->isSuperClassOf(BoundInterface) ||
3381*67e74705SXin Li            BoundInterface->isSuperClassOf(MethodInterface);
3382*67e74705SXin Li   }
3383*67e74705SXin Li   llvm_unreachable("unknow method context");
3384*67e74705SXin Li }
3385*67e74705SXin Li 
3386*67e74705SXin Li /// We first select the type of the method: Instance or Factory, then collect
3387*67e74705SXin Li /// all methods with that type.
CollectMultipleMethodsInGlobalPool(Selector Sel,SmallVectorImpl<ObjCMethodDecl * > & Methods,bool InstanceFirst,bool CheckTheOther,const ObjCObjectType * TypeBound)3388*67e74705SXin Li bool Sema::CollectMultipleMethodsInGlobalPool(
3389*67e74705SXin Li     Selector Sel, SmallVectorImpl<ObjCMethodDecl *> &Methods,
3390*67e74705SXin Li     bool InstanceFirst, bool CheckTheOther,
3391*67e74705SXin Li     const ObjCObjectType *TypeBound) {
3392*67e74705SXin Li   if (ExternalSource)
3393*67e74705SXin Li     ReadMethodPool(Sel);
3394*67e74705SXin Li 
3395*67e74705SXin Li   GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
3396*67e74705SXin Li   if (Pos == MethodPool.end())
3397*67e74705SXin Li     return false;
3398*67e74705SXin Li 
3399*67e74705SXin Li   // Gather the non-hidden methods.
3400*67e74705SXin Li   ObjCMethodList &MethList = InstanceFirst ? Pos->second.first :
3401*67e74705SXin Li                              Pos->second.second;
3402*67e74705SXin Li   for (ObjCMethodList *M = &MethList; M; M = M->getNext())
3403*67e74705SXin Li     if (M->getMethod() && !M->getMethod()->isHidden()) {
3404*67e74705SXin Li       if (FilterMethodsByTypeBound(M->getMethod(), TypeBound))
3405*67e74705SXin Li         Methods.push_back(M->getMethod());
3406*67e74705SXin Li     }
3407*67e74705SXin Li 
3408*67e74705SXin Li   // Return if we find any method with the desired kind.
3409*67e74705SXin Li   if (!Methods.empty())
3410*67e74705SXin Li     return Methods.size() > 1;
3411*67e74705SXin Li 
3412*67e74705SXin Li   if (!CheckTheOther)
3413*67e74705SXin Li     return false;
3414*67e74705SXin Li 
3415*67e74705SXin Li   // Gather the other kind.
3416*67e74705SXin Li   ObjCMethodList &MethList2 = InstanceFirst ? Pos->second.second :
3417*67e74705SXin Li                               Pos->second.first;
3418*67e74705SXin Li   for (ObjCMethodList *M = &MethList2; M; M = M->getNext())
3419*67e74705SXin Li     if (M->getMethod() && !M->getMethod()->isHidden()) {
3420*67e74705SXin Li       if (FilterMethodsByTypeBound(M->getMethod(), TypeBound))
3421*67e74705SXin Li         Methods.push_back(M->getMethod());
3422*67e74705SXin Li     }
3423*67e74705SXin Li 
3424*67e74705SXin Li   return Methods.size() > 1;
3425*67e74705SXin Li }
3426*67e74705SXin Li 
AreMultipleMethodsInGlobalPool(Selector Sel,ObjCMethodDecl * BestMethod,SourceRange R,bool receiverIdOrClass,SmallVectorImpl<ObjCMethodDecl * > & Methods)3427*67e74705SXin Li bool Sema::AreMultipleMethodsInGlobalPool(
3428*67e74705SXin Li     Selector Sel, ObjCMethodDecl *BestMethod, SourceRange R,
3429*67e74705SXin Li     bool receiverIdOrClass, SmallVectorImpl<ObjCMethodDecl *> &Methods) {
3430*67e74705SXin Li   // Diagnose finding more than one method in global pool.
3431*67e74705SXin Li   SmallVector<ObjCMethodDecl *, 4> FilteredMethods;
3432*67e74705SXin Li   FilteredMethods.push_back(BestMethod);
3433*67e74705SXin Li 
3434*67e74705SXin Li   for (auto *M : Methods)
3435*67e74705SXin Li     if (M != BestMethod && !M->hasAttr<UnavailableAttr>())
3436*67e74705SXin Li       FilteredMethods.push_back(M);
3437*67e74705SXin Li 
3438*67e74705SXin Li   if (FilteredMethods.size() > 1)
3439*67e74705SXin Li     DiagnoseMultipleMethodInGlobalPool(FilteredMethods, Sel, R,
3440*67e74705SXin Li                                        receiverIdOrClass);
3441*67e74705SXin Li 
3442*67e74705SXin Li   GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
3443*67e74705SXin Li   // Test for no method in the pool which should not trigger any warning by
3444*67e74705SXin Li   // caller.
3445*67e74705SXin Li   if (Pos == MethodPool.end())
3446*67e74705SXin Li     return true;
3447*67e74705SXin Li   ObjCMethodList &MethList =
3448*67e74705SXin Li     BestMethod->isInstanceMethod() ? Pos->second.first : Pos->second.second;
3449*67e74705SXin Li   return MethList.hasMoreThanOneDecl();
3450*67e74705SXin Li }
3451*67e74705SXin Li 
LookupMethodInGlobalPool(Selector Sel,SourceRange R,bool receiverIdOrClass,bool instance)3452*67e74705SXin Li ObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R,
3453*67e74705SXin Li                                                bool receiverIdOrClass,
3454*67e74705SXin Li                                                bool instance) {
3455*67e74705SXin Li   if (ExternalSource)
3456*67e74705SXin Li     ReadMethodPool(Sel);
3457*67e74705SXin Li 
3458*67e74705SXin Li   GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
3459*67e74705SXin Li   if (Pos == MethodPool.end())
3460*67e74705SXin Li     return nullptr;
3461*67e74705SXin Li 
3462*67e74705SXin Li   // Gather the non-hidden methods.
3463*67e74705SXin Li   ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second;
3464*67e74705SXin Li   SmallVector<ObjCMethodDecl *, 4> Methods;
3465*67e74705SXin Li   for (ObjCMethodList *M = &MethList; M; M = M->getNext()) {
3466*67e74705SXin Li     if (M->getMethod() && !M->getMethod()->isHidden())
3467*67e74705SXin Li       return M->getMethod();
3468*67e74705SXin Li   }
3469*67e74705SXin Li   return nullptr;
3470*67e74705SXin Li }
3471*67e74705SXin Li 
DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl * > & Methods,Selector Sel,SourceRange R,bool receiverIdOrClass)3472*67e74705SXin Li void Sema::DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl*> &Methods,
3473*67e74705SXin Li                                               Selector Sel, SourceRange R,
3474*67e74705SXin Li                                               bool receiverIdOrClass) {
3475*67e74705SXin Li   // We found multiple methods, so we may have to complain.
3476*67e74705SXin Li   bool issueDiagnostic = false, issueError = false;
3477*67e74705SXin Li 
3478*67e74705SXin Li   // We support a warning which complains about *any* difference in
3479*67e74705SXin Li   // method signature.
3480*67e74705SXin Li   bool strictSelectorMatch =
3481*67e74705SXin Li   receiverIdOrClass &&
3482*67e74705SXin Li   !Diags.isIgnored(diag::warn_strict_multiple_method_decl, R.getBegin());
3483*67e74705SXin Li   if (strictSelectorMatch) {
3484*67e74705SXin Li     for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
3485*67e74705SXin Li       if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_strict)) {
3486*67e74705SXin Li         issueDiagnostic = true;
3487*67e74705SXin Li         break;
3488*67e74705SXin Li       }
3489*67e74705SXin Li     }
3490*67e74705SXin Li   }
3491*67e74705SXin Li 
3492*67e74705SXin Li   // If we didn't see any strict differences, we won't see any loose
3493*67e74705SXin Li   // differences.  In ARC, however, we also need to check for loose
3494*67e74705SXin Li   // mismatches, because most of them are errors.
3495*67e74705SXin Li   if (!strictSelectorMatch ||
3496*67e74705SXin Li       (issueDiagnostic && getLangOpts().ObjCAutoRefCount))
3497*67e74705SXin Li     for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
3498*67e74705SXin Li       // This checks if the methods differ in type mismatch.
3499*67e74705SXin Li       if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_loose) &&
3500*67e74705SXin Li           !isAcceptableMethodMismatch(Methods[0], Methods[I])) {
3501*67e74705SXin Li         issueDiagnostic = true;
3502*67e74705SXin Li         if (getLangOpts().ObjCAutoRefCount)
3503*67e74705SXin Li           issueError = true;
3504*67e74705SXin Li         break;
3505*67e74705SXin Li       }
3506*67e74705SXin Li     }
3507*67e74705SXin Li 
3508*67e74705SXin Li   if (issueDiagnostic) {
3509*67e74705SXin Li     if (issueError)
3510*67e74705SXin Li       Diag(R.getBegin(), diag::err_arc_multiple_method_decl) << Sel << R;
3511*67e74705SXin Li     else if (strictSelectorMatch)
3512*67e74705SXin Li       Diag(R.getBegin(), diag::warn_strict_multiple_method_decl) << Sel << R;
3513*67e74705SXin Li     else
3514*67e74705SXin Li       Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
3515*67e74705SXin Li 
3516*67e74705SXin Li     Diag(Methods[0]->getLocStart(),
3517*67e74705SXin Li          issueError ? diag::note_possibility : diag::note_using)
3518*67e74705SXin Li     << Methods[0]->getSourceRange();
3519*67e74705SXin Li     for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
3520*67e74705SXin Li       Diag(Methods[I]->getLocStart(), diag::note_also_found)
3521*67e74705SXin Li       << Methods[I]->getSourceRange();
3522*67e74705SXin Li     }
3523*67e74705SXin Li   }
3524*67e74705SXin Li }
3525*67e74705SXin Li 
LookupImplementedMethodInGlobalPool(Selector Sel)3526*67e74705SXin Li ObjCMethodDecl *Sema::LookupImplementedMethodInGlobalPool(Selector Sel) {
3527*67e74705SXin Li   GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
3528*67e74705SXin Li   if (Pos == MethodPool.end())
3529*67e74705SXin Li     return nullptr;
3530*67e74705SXin Li 
3531*67e74705SXin Li   GlobalMethods &Methods = Pos->second;
3532*67e74705SXin Li   for (const ObjCMethodList *Method = &Methods.first; Method;
3533*67e74705SXin Li        Method = Method->getNext())
3534*67e74705SXin Li     if (Method->getMethod() &&
3535*67e74705SXin Li         (Method->getMethod()->isDefined() ||
3536*67e74705SXin Li          Method->getMethod()->isPropertyAccessor()))
3537*67e74705SXin Li       return Method->getMethod();
3538*67e74705SXin Li 
3539*67e74705SXin Li   for (const ObjCMethodList *Method = &Methods.second; Method;
3540*67e74705SXin Li        Method = Method->getNext())
3541*67e74705SXin Li     if (Method->getMethod() &&
3542*67e74705SXin Li         (Method->getMethod()->isDefined() ||
3543*67e74705SXin Li          Method->getMethod()->isPropertyAccessor()))
3544*67e74705SXin Li       return Method->getMethod();
3545*67e74705SXin Li   return nullptr;
3546*67e74705SXin Li }
3547*67e74705SXin Li 
3548*67e74705SXin Li static void
HelperSelectorsForTypoCorrection(SmallVectorImpl<const ObjCMethodDecl * > & BestMethod,StringRef Typo,const ObjCMethodDecl * Method)3549*67e74705SXin Li HelperSelectorsForTypoCorrection(
3550*67e74705SXin Li                       SmallVectorImpl<const ObjCMethodDecl *> &BestMethod,
3551*67e74705SXin Li                       StringRef Typo, const ObjCMethodDecl * Method) {
3552*67e74705SXin Li   const unsigned MaxEditDistance = 1;
3553*67e74705SXin Li   unsigned BestEditDistance = MaxEditDistance + 1;
3554*67e74705SXin Li   std::string MethodName = Method->getSelector().getAsString();
3555*67e74705SXin Li 
3556*67e74705SXin Li   unsigned MinPossibleEditDistance = abs((int)MethodName.size() - (int)Typo.size());
3557*67e74705SXin Li   if (MinPossibleEditDistance > 0 &&
3558*67e74705SXin Li       Typo.size() / MinPossibleEditDistance < 1)
3559*67e74705SXin Li     return;
3560*67e74705SXin Li   unsigned EditDistance = Typo.edit_distance(MethodName, true, MaxEditDistance);
3561*67e74705SXin Li   if (EditDistance > MaxEditDistance)
3562*67e74705SXin Li     return;
3563*67e74705SXin Li   if (EditDistance == BestEditDistance)
3564*67e74705SXin Li     BestMethod.push_back(Method);
3565*67e74705SXin Li   else if (EditDistance < BestEditDistance) {
3566*67e74705SXin Li     BestMethod.clear();
3567*67e74705SXin Li     BestMethod.push_back(Method);
3568*67e74705SXin Li   }
3569*67e74705SXin Li }
3570*67e74705SXin Li 
HelperIsMethodInObjCType(Sema & S,Selector Sel,QualType ObjectType)3571*67e74705SXin Li static bool HelperIsMethodInObjCType(Sema &S, Selector Sel,
3572*67e74705SXin Li                                      QualType ObjectType) {
3573*67e74705SXin Li   if (ObjectType.isNull())
3574*67e74705SXin Li     return true;
3575*67e74705SXin Li   if (S.LookupMethodInObjectType(Sel, ObjectType, true/*Instance method*/))
3576*67e74705SXin Li     return true;
3577*67e74705SXin Li   return S.LookupMethodInObjectType(Sel, ObjectType, false/*Class method*/) !=
3578*67e74705SXin Li          nullptr;
3579*67e74705SXin Li }
3580*67e74705SXin Li 
3581*67e74705SXin Li const ObjCMethodDecl *
SelectorsForTypoCorrection(Selector Sel,QualType ObjectType)3582*67e74705SXin Li Sema::SelectorsForTypoCorrection(Selector Sel,
3583*67e74705SXin Li                                  QualType ObjectType) {
3584*67e74705SXin Li   unsigned NumArgs = Sel.getNumArgs();
3585*67e74705SXin Li   SmallVector<const ObjCMethodDecl *, 8> Methods;
3586*67e74705SXin Li   bool ObjectIsId = true, ObjectIsClass = true;
3587*67e74705SXin Li   if (ObjectType.isNull())
3588*67e74705SXin Li     ObjectIsId = ObjectIsClass = false;
3589*67e74705SXin Li   else if (!ObjectType->isObjCObjectPointerType())
3590*67e74705SXin Li     return nullptr;
3591*67e74705SXin Li   else if (const ObjCObjectPointerType *ObjCPtr =
3592*67e74705SXin Li            ObjectType->getAsObjCInterfacePointerType()) {
3593*67e74705SXin Li     ObjectType = QualType(ObjCPtr->getInterfaceType(), 0);
3594*67e74705SXin Li     ObjectIsId = ObjectIsClass = false;
3595*67e74705SXin Li   }
3596*67e74705SXin Li   else if (ObjectType->isObjCIdType() || ObjectType->isObjCQualifiedIdType())
3597*67e74705SXin Li     ObjectIsClass = false;
3598*67e74705SXin Li   else if (ObjectType->isObjCClassType() || ObjectType->isObjCQualifiedClassType())
3599*67e74705SXin Li     ObjectIsId = false;
3600*67e74705SXin Li   else
3601*67e74705SXin Li     return nullptr;
3602*67e74705SXin Li 
3603*67e74705SXin Li   for (GlobalMethodPool::iterator b = MethodPool.begin(),
3604*67e74705SXin Li        e = MethodPool.end(); b != e; b++) {
3605*67e74705SXin Li     // instance methods
3606*67e74705SXin Li     for (ObjCMethodList *M = &b->second.first; M; M=M->getNext())
3607*67e74705SXin Li       if (M->getMethod() &&
3608*67e74705SXin Li           (M->getMethod()->getSelector().getNumArgs() == NumArgs) &&
3609*67e74705SXin Li           (M->getMethod()->getSelector() != Sel)) {
3610*67e74705SXin Li         if (ObjectIsId)
3611*67e74705SXin Li           Methods.push_back(M->getMethod());
3612*67e74705SXin Li         else if (!ObjectIsClass &&
3613*67e74705SXin Li                  HelperIsMethodInObjCType(*this, M->getMethod()->getSelector(),
3614*67e74705SXin Li                                           ObjectType))
3615*67e74705SXin Li           Methods.push_back(M->getMethod());
3616*67e74705SXin Li       }
3617*67e74705SXin Li     // class methods
3618*67e74705SXin Li     for (ObjCMethodList *M = &b->second.second; M; M=M->getNext())
3619*67e74705SXin Li       if (M->getMethod() &&
3620*67e74705SXin Li           (M->getMethod()->getSelector().getNumArgs() == NumArgs) &&
3621*67e74705SXin Li           (M->getMethod()->getSelector() != Sel)) {
3622*67e74705SXin Li         if (ObjectIsClass)
3623*67e74705SXin Li           Methods.push_back(M->getMethod());
3624*67e74705SXin Li         else if (!ObjectIsId &&
3625*67e74705SXin Li                  HelperIsMethodInObjCType(*this, M->getMethod()->getSelector(),
3626*67e74705SXin Li                                           ObjectType))
3627*67e74705SXin Li           Methods.push_back(M->getMethod());
3628*67e74705SXin Li       }
3629*67e74705SXin Li   }
3630*67e74705SXin Li 
3631*67e74705SXin Li   SmallVector<const ObjCMethodDecl *, 8> SelectedMethods;
3632*67e74705SXin Li   for (unsigned i = 0, e = Methods.size(); i < e; i++) {
3633*67e74705SXin Li     HelperSelectorsForTypoCorrection(SelectedMethods,
3634*67e74705SXin Li                                      Sel.getAsString(), Methods[i]);
3635*67e74705SXin Li   }
3636*67e74705SXin Li   return (SelectedMethods.size() == 1) ? SelectedMethods[0] : nullptr;
3637*67e74705SXin Li }
3638*67e74705SXin Li 
3639*67e74705SXin Li /// DiagnoseDuplicateIvars -
3640*67e74705SXin Li /// Check for duplicate ivars in the entire class at the start of
3641*67e74705SXin Li /// \@implementation. This becomes necesssary because class extension can
3642*67e74705SXin Li /// add ivars to a class in random order which will not be known until
3643*67e74705SXin Li /// class's \@implementation is seen.
DiagnoseDuplicateIvars(ObjCInterfaceDecl * ID,ObjCInterfaceDecl * SID)3644*67e74705SXin Li void Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID,
3645*67e74705SXin Li                                   ObjCInterfaceDecl *SID) {
3646*67e74705SXin Li   for (auto *Ivar : ID->ivars()) {
3647*67e74705SXin Li     if (Ivar->isInvalidDecl())
3648*67e74705SXin Li       continue;
3649*67e74705SXin Li     if (IdentifierInfo *II = Ivar->getIdentifier()) {
3650*67e74705SXin Li       ObjCIvarDecl* prevIvar = SID->lookupInstanceVariable(II);
3651*67e74705SXin Li       if (prevIvar) {
3652*67e74705SXin Li         Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;
3653*67e74705SXin Li         Diag(prevIvar->getLocation(), diag::note_previous_declaration);
3654*67e74705SXin Li         Ivar->setInvalidDecl();
3655*67e74705SXin Li       }
3656*67e74705SXin Li     }
3657*67e74705SXin Li   }
3658*67e74705SXin Li }
3659*67e74705SXin Li 
3660*67e74705SXin Li /// Diagnose attempts to define ARC-__weak ivars when __weak is disabled.
DiagnoseWeakIvars(Sema & S,ObjCImplementationDecl * ID)3661*67e74705SXin Li static void DiagnoseWeakIvars(Sema &S, ObjCImplementationDecl *ID) {
3662*67e74705SXin Li   if (S.getLangOpts().ObjCWeak) return;
3663*67e74705SXin Li 
3664*67e74705SXin Li   for (auto ivar = ID->getClassInterface()->all_declared_ivar_begin();
3665*67e74705SXin Li          ivar; ivar = ivar->getNextIvar()) {
3666*67e74705SXin Li     if (ivar->isInvalidDecl()) continue;
3667*67e74705SXin Li     if (ivar->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
3668*67e74705SXin Li       if (S.getLangOpts().ObjCWeakRuntime) {
3669*67e74705SXin Li         S.Diag(ivar->getLocation(), diag::err_arc_weak_disabled);
3670*67e74705SXin Li       } else {
3671*67e74705SXin Li         S.Diag(ivar->getLocation(), diag::err_arc_weak_no_runtime);
3672*67e74705SXin Li       }
3673*67e74705SXin Li     }
3674*67e74705SXin Li   }
3675*67e74705SXin Li }
3676*67e74705SXin Li 
getObjCContainerKind() const3677*67e74705SXin Li Sema::ObjCContainerKind Sema::getObjCContainerKind() const {
3678*67e74705SXin Li   switch (CurContext->getDeclKind()) {
3679*67e74705SXin Li     case Decl::ObjCInterface:
3680*67e74705SXin Li       return Sema::OCK_Interface;
3681*67e74705SXin Li     case Decl::ObjCProtocol:
3682*67e74705SXin Li       return Sema::OCK_Protocol;
3683*67e74705SXin Li     case Decl::ObjCCategory:
3684*67e74705SXin Li       if (cast<ObjCCategoryDecl>(CurContext)->IsClassExtension())
3685*67e74705SXin Li         return Sema::OCK_ClassExtension;
3686*67e74705SXin Li       return Sema::OCK_Category;
3687*67e74705SXin Li     case Decl::ObjCImplementation:
3688*67e74705SXin Li       return Sema::OCK_Implementation;
3689*67e74705SXin Li     case Decl::ObjCCategoryImpl:
3690*67e74705SXin Li       return Sema::OCK_CategoryImplementation;
3691*67e74705SXin Li 
3692*67e74705SXin Li     default:
3693*67e74705SXin Li       return Sema::OCK_None;
3694*67e74705SXin Li   }
3695*67e74705SXin Li }
3696*67e74705SXin Li 
3697*67e74705SXin Li // Note: For class/category implementations, allMethods is always null.
ActOnAtEnd(Scope * S,SourceRange AtEnd,ArrayRef<Decl * > allMethods,ArrayRef<DeclGroupPtrTy> allTUVars)3698*67e74705SXin Li Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods,
3699*67e74705SXin Li                        ArrayRef<DeclGroupPtrTy> allTUVars) {
3700*67e74705SXin Li   if (getObjCContainerKind() == Sema::OCK_None)
3701*67e74705SXin Li     return nullptr;
3702*67e74705SXin Li 
3703*67e74705SXin Li   assert(AtEnd.isValid() && "Invalid location for '@end'");
3704*67e74705SXin Li 
3705*67e74705SXin Li   ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
3706*67e74705SXin Li   Decl *ClassDecl = cast<Decl>(OCD);
3707*67e74705SXin Li 
3708*67e74705SXin Li   bool isInterfaceDeclKind =
3709*67e74705SXin Li         isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl)
3710*67e74705SXin Li          || isa<ObjCProtocolDecl>(ClassDecl);
3711*67e74705SXin Li   bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl);
3712*67e74705SXin Li 
3713*67e74705SXin Li   // FIXME: Remove these and use the ObjCContainerDecl/DeclContext.
3714*67e74705SXin Li   llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;
3715*67e74705SXin Li   llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;
3716*67e74705SXin Li 
3717*67e74705SXin Li   for (unsigned i = 0, e = allMethods.size(); i != e; i++ ) {
3718*67e74705SXin Li     ObjCMethodDecl *Method =
3719*67e74705SXin Li       cast_or_null<ObjCMethodDecl>(allMethods[i]);
3720*67e74705SXin Li 
3721*67e74705SXin Li     if (!Method) continue;  // Already issued a diagnostic.
3722*67e74705SXin Li     if (Method->isInstanceMethod()) {
3723*67e74705SXin Li       /// Check for instance method of the same name with incompatible types
3724*67e74705SXin Li       const ObjCMethodDecl *&PrevMethod = InsMap[Method->getSelector()];
3725*67e74705SXin Li       bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
3726*67e74705SXin Li                               : false;
3727*67e74705SXin Li       if ((isInterfaceDeclKind && PrevMethod && !match)
3728*67e74705SXin Li           || (checkIdenticalMethods && match)) {
3729*67e74705SXin Li           Diag(Method->getLocation(), diag::err_duplicate_method_decl)
3730*67e74705SXin Li             << Method->getDeclName();
3731*67e74705SXin Li           Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
3732*67e74705SXin Li         Method->setInvalidDecl();
3733*67e74705SXin Li       } else {
3734*67e74705SXin Li         if (PrevMethod) {
3735*67e74705SXin Li           Method->setAsRedeclaration(PrevMethod);
3736*67e74705SXin Li           if (!Context.getSourceManager().isInSystemHeader(
3737*67e74705SXin Li                  Method->getLocation()))
3738*67e74705SXin Li             Diag(Method->getLocation(), diag::warn_duplicate_method_decl)
3739*67e74705SXin Li               << Method->getDeclName();
3740*67e74705SXin Li           Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
3741*67e74705SXin Li         }
3742*67e74705SXin Li         InsMap[Method->getSelector()] = Method;
3743*67e74705SXin Li         /// The following allows us to typecheck messages to "id".
3744*67e74705SXin Li         AddInstanceMethodToGlobalPool(Method);
3745*67e74705SXin Li       }
3746*67e74705SXin Li     } else {
3747*67e74705SXin Li       /// Check for class method of the same name with incompatible types
3748*67e74705SXin Li       const ObjCMethodDecl *&PrevMethod = ClsMap[Method->getSelector()];
3749*67e74705SXin Li       bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
3750*67e74705SXin Li                               : false;
3751*67e74705SXin Li       if ((isInterfaceDeclKind && PrevMethod && !match)
3752*67e74705SXin Li           || (checkIdenticalMethods && match)) {
3753*67e74705SXin Li         Diag(Method->getLocation(), diag::err_duplicate_method_decl)
3754*67e74705SXin Li           << Method->getDeclName();
3755*67e74705SXin Li         Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
3756*67e74705SXin Li         Method->setInvalidDecl();
3757*67e74705SXin Li       } else {
3758*67e74705SXin Li         if (PrevMethod) {
3759*67e74705SXin Li           Method->setAsRedeclaration(PrevMethod);
3760*67e74705SXin Li           if (!Context.getSourceManager().isInSystemHeader(
3761*67e74705SXin Li                  Method->getLocation()))
3762*67e74705SXin Li             Diag(Method->getLocation(), diag::warn_duplicate_method_decl)
3763*67e74705SXin Li               << Method->getDeclName();
3764*67e74705SXin Li           Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
3765*67e74705SXin Li         }
3766*67e74705SXin Li         ClsMap[Method->getSelector()] = Method;
3767*67e74705SXin Li         AddFactoryMethodToGlobalPool(Method);
3768*67e74705SXin Li       }
3769*67e74705SXin Li     }
3770*67e74705SXin Li   }
3771*67e74705SXin Li   if (isa<ObjCInterfaceDecl>(ClassDecl)) {
3772*67e74705SXin Li     // Nothing to do here.
3773*67e74705SXin Li   } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
3774*67e74705SXin Li     // Categories are used to extend the class by declaring new methods.
3775*67e74705SXin Li     // By the same token, they are also used to add new properties. No
3776*67e74705SXin Li     // need to compare the added property to those in the class.
3777*67e74705SXin Li 
3778*67e74705SXin Li     if (C->IsClassExtension()) {
3779*67e74705SXin Li       ObjCInterfaceDecl *CCPrimary = C->getClassInterface();
3780*67e74705SXin Li       DiagnoseClassExtensionDupMethods(C, CCPrimary);
3781*67e74705SXin Li     }
3782*67e74705SXin Li   }
3783*67e74705SXin Li   if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(ClassDecl)) {
3784*67e74705SXin Li     if (CDecl->getIdentifier())
3785*67e74705SXin Li       // ProcessPropertyDecl is responsible for diagnosing conflicts with any
3786*67e74705SXin Li       // user-defined setter/getter. It also synthesizes setter/getter methods
3787*67e74705SXin Li       // and adds them to the DeclContext and global method pools.
3788*67e74705SXin Li       for (auto *I : CDecl->properties())
3789*67e74705SXin Li         ProcessPropertyDecl(I);
3790*67e74705SXin Li     CDecl->setAtEndRange(AtEnd);
3791*67e74705SXin Li   }
3792*67e74705SXin Li   if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
3793*67e74705SXin Li     IC->setAtEndRange(AtEnd);
3794*67e74705SXin Li     if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) {
3795*67e74705SXin Li       // Any property declared in a class extension might have user
3796*67e74705SXin Li       // declared setter or getter in current class extension or one
3797*67e74705SXin Li       // of the other class extensions. Mark them as synthesized as
3798*67e74705SXin Li       // property will be synthesized when property with same name is
3799*67e74705SXin Li       // seen in the @implementation.
3800*67e74705SXin Li       for (const auto *Ext : IDecl->visible_extensions()) {
3801*67e74705SXin Li         for (const auto *Property : Ext->instance_properties()) {
3802*67e74705SXin Li           // Skip over properties declared @dynamic
3803*67e74705SXin Li           if (const ObjCPropertyImplDecl *PIDecl
3804*67e74705SXin Li               = IC->FindPropertyImplDecl(Property->getIdentifier(),
3805*67e74705SXin Li                                          Property->getQueryKind()))
3806*67e74705SXin Li             if (PIDecl->getPropertyImplementation()
3807*67e74705SXin Li                   == ObjCPropertyImplDecl::Dynamic)
3808*67e74705SXin Li               continue;
3809*67e74705SXin Li 
3810*67e74705SXin Li           for (const auto *Ext : IDecl->visible_extensions()) {
3811*67e74705SXin Li             if (ObjCMethodDecl *GetterMethod
3812*67e74705SXin Li                   = Ext->getInstanceMethod(Property->getGetterName()))
3813*67e74705SXin Li               GetterMethod->setPropertyAccessor(true);
3814*67e74705SXin Li             if (!Property->isReadOnly())
3815*67e74705SXin Li               if (ObjCMethodDecl *SetterMethod
3816*67e74705SXin Li                     = Ext->getInstanceMethod(Property->getSetterName()))
3817*67e74705SXin Li                 SetterMethod->setPropertyAccessor(true);
3818*67e74705SXin Li           }
3819*67e74705SXin Li         }
3820*67e74705SXin Li       }
3821*67e74705SXin Li       ImplMethodsVsClassMethods(S, IC, IDecl);
3822*67e74705SXin Li       AtomicPropertySetterGetterRules(IC, IDecl);
3823*67e74705SXin Li       DiagnoseOwningPropertyGetterSynthesis(IC);
3824*67e74705SXin Li       DiagnoseUnusedBackingIvarInAccessor(S, IC);
3825*67e74705SXin Li       if (IDecl->hasDesignatedInitializers())
3826*67e74705SXin Li         DiagnoseMissingDesignatedInitOverrides(IC, IDecl);
3827*67e74705SXin Li       DiagnoseWeakIvars(*this, IC);
3828*67e74705SXin Li 
3829*67e74705SXin Li       bool HasRootClassAttr = IDecl->hasAttr<ObjCRootClassAttr>();
3830*67e74705SXin Li       if (IDecl->getSuperClass() == nullptr) {
3831*67e74705SXin Li         // This class has no superclass, so check that it has been marked with
3832*67e74705SXin Li         // __attribute((objc_root_class)).
3833*67e74705SXin Li         if (!HasRootClassAttr) {
3834*67e74705SXin Li           SourceLocation DeclLoc(IDecl->getLocation());
3835*67e74705SXin Li           SourceLocation SuperClassLoc(getLocForEndOfToken(DeclLoc));
3836*67e74705SXin Li           Diag(DeclLoc, diag::warn_objc_root_class_missing)
3837*67e74705SXin Li             << IDecl->getIdentifier();
3838*67e74705SXin Li           // See if NSObject is in the current scope, and if it is, suggest
3839*67e74705SXin Li           // adding " : NSObject " to the class declaration.
3840*67e74705SXin Li           NamedDecl *IF = LookupSingleName(TUScope,
3841*67e74705SXin Li                                            NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject),
3842*67e74705SXin Li                                            DeclLoc, LookupOrdinaryName);
3843*67e74705SXin Li           ObjCInterfaceDecl *NSObjectDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
3844*67e74705SXin Li           if (NSObjectDecl && NSObjectDecl->getDefinition()) {
3845*67e74705SXin Li             Diag(SuperClassLoc, diag::note_objc_needs_superclass)
3846*67e74705SXin Li               << FixItHint::CreateInsertion(SuperClassLoc, " : NSObject ");
3847*67e74705SXin Li           } else {
3848*67e74705SXin Li             Diag(SuperClassLoc, diag::note_objc_needs_superclass);
3849*67e74705SXin Li           }
3850*67e74705SXin Li         }
3851*67e74705SXin Li       } else if (HasRootClassAttr) {
3852*67e74705SXin Li         // Complain that only root classes may have this attribute.
3853*67e74705SXin Li         Diag(IDecl->getLocation(), diag::err_objc_root_class_subclass);
3854*67e74705SXin Li       }
3855*67e74705SXin Li 
3856*67e74705SXin Li       if (LangOpts.ObjCRuntime.isNonFragile()) {
3857*67e74705SXin Li         while (IDecl->getSuperClass()) {
3858*67e74705SXin Li           DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass());
3859*67e74705SXin Li           IDecl = IDecl->getSuperClass();
3860*67e74705SXin Li         }
3861*67e74705SXin Li       }
3862*67e74705SXin Li     }
3863*67e74705SXin Li     SetIvarInitializers(IC);
3864*67e74705SXin Li   } else if (ObjCCategoryImplDecl* CatImplClass =
3865*67e74705SXin Li                                    dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
3866*67e74705SXin Li     CatImplClass->setAtEndRange(AtEnd);
3867*67e74705SXin Li 
3868*67e74705SXin Li     // Find category interface decl and then check that all methods declared
3869*67e74705SXin Li     // in this interface are implemented in the category @implementation.
3870*67e74705SXin Li     if (ObjCInterfaceDecl* IDecl = CatImplClass->getClassInterface()) {
3871*67e74705SXin Li       if (ObjCCategoryDecl *Cat
3872*67e74705SXin Li             = IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier())) {
3873*67e74705SXin Li         ImplMethodsVsClassMethods(S, CatImplClass, Cat);
3874*67e74705SXin Li       }
3875*67e74705SXin Li     }
3876*67e74705SXin Li   }
3877*67e74705SXin Li   if (isInterfaceDeclKind) {
3878*67e74705SXin Li     // Reject invalid vardecls.
3879*67e74705SXin Li     for (unsigned i = 0, e = allTUVars.size(); i != e; i++) {
3880*67e74705SXin Li       DeclGroupRef DG = allTUVars[i].get();
3881*67e74705SXin Li       for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
3882*67e74705SXin Li         if (VarDecl *VDecl = dyn_cast<VarDecl>(*I)) {
3883*67e74705SXin Li           if (!VDecl->hasExternalStorage())
3884*67e74705SXin Li             Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass);
3885*67e74705SXin Li         }
3886*67e74705SXin Li     }
3887*67e74705SXin Li   }
3888*67e74705SXin Li   ActOnObjCContainerFinishDefinition();
3889*67e74705SXin Li 
3890*67e74705SXin Li   for (unsigned i = 0, e = allTUVars.size(); i != e; i++) {
3891*67e74705SXin Li     DeclGroupRef DG = allTUVars[i].get();
3892*67e74705SXin Li     for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
3893*67e74705SXin Li       (*I)->setTopLevelDeclInObjCContainer();
3894*67e74705SXin Li     Consumer.HandleTopLevelDeclInObjCContainer(DG);
3895*67e74705SXin Li   }
3896*67e74705SXin Li 
3897*67e74705SXin Li   ActOnDocumentableDecl(ClassDecl);
3898*67e74705SXin Li   return ClassDecl;
3899*67e74705SXin Li }
3900*67e74705SXin Li 
3901*67e74705SXin Li /// CvtQTToAstBitMask - utility routine to produce an AST bitmask for
3902*67e74705SXin Li /// objective-c's type qualifier from the parser version of the same info.
3903*67e74705SXin Li static Decl::ObjCDeclQualifier
CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal)3904*67e74705SXin Li CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) {
3905*67e74705SXin Li   return (Decl::ObjCDeclQualifier) (unsigned) PQTVal;
3906*67e74705SXin Li }
3907*67e74705SXin Li 
3908*67e74705SXin Li /// \brief Check whether the declared result type of the given Objective-C
3909*67e74705SXin Li /// method declaration is compatible with the method's class.
3910*67e74705SXin Li ///
3911*67e74705SXin Li static Sema::ResultTypeCompatibilityKind
CheckRelatedResultTypeCompatibility(Sema & S,ObjCMethodDecl * Method,ObjCInterfaceDecl * CurrentClass)3912*67e74705SXin Li CheckRelatedResultTypeCompatibility(Sema &S, ObjCMethodDecl *Method,
3913*67e74705SXin Li                                     ObjCInterfaceDecl *CurrentClass) {
3914*67e74705SXin Li   QualType ResultType = Method->getReturnType();
3915*67e74705SXin Li 
3916*67e74705SXin Li   // If an Objective-C method inherits its related result type, then its
3917*67e74705SXin Li   // declared result type must be compatible with its own class type. The
3918*67e74705SXin Li   // declared result type is compatible if:
3919*67e74705SXin Li   if (const ObjCObjectPointerType *ResultObjectType
3920*67e74705SXin Li                                 = ResultType->getAs<ObjCObjectPointerType>()) {
3921*67e74705SXin Li     //   - it is id or qualified id, or
3922*67e74705SXin Li     if (ResultObjectType->isObjCIdType() ||
3923*67e74705SXin Li         ResultObjectType->isObjCQualifiedIdType())
3924*67e74705SXin Li       return Sema::RTC_Compatible;
3925*67e74705SXin Li 
3926*67e74705SXin Li     if (CurrentClass) {
3927*67e74705SXin Li       if (ObjCInterfaceDecl *ResultClass
3928*67e74705SXin Li                                       = ResultObjectType->getInterfaceDecl()) {
3929*67e74705SXin Li         //   - it is the same as the method's class type, or
3930*67e74705SXin Li         if (declaresSameEntity(CurrentClass, ResultClass))
3931*67e74705SXin Li           return Sema::RTC_Compatible;
3932*67e74705SXin Li 
3933*67e74705SXin Li         //   - it is a superclass of the method's class type
3934*67e74705SXin Li         if (ResultClass->isSuperClassOf(CurrentClass))
3935*67e74705SXin Li           return Sema::RTC_Compatible;
3936*67e74705SXin Li       }
3937*67e74705SXin Li     } else {
3938*67e74705SXin Li       // Any Objective-C pointer type might be acceptable for a protocol
3939*67e74705SXin Li       // method; we just don't know.
3940*67e74705SXin Li       return Sema::RTC_Unknown;
3941*67e74705SXin Li     }
3942*67e74705SXin Li   }
3943*67e74705SXin Li 
3944*67e74705SXin Li   return Sema::RTC_Incompatible;
3945*67e74705SXin Li }
3946*67e74705SXin Li 
3947*67e74705SXin Li namespace {
3948*67e74705SXin Li /// A helper class for searching for methods which a particular method
3949*67e74705SXin Li /// overrides.
3950*67e74705SXin Li class OverrideSearch {
3951*67e74705SXin Li public:
3952*67e74705SXin Li   Sema &S;
3953*67e74705SXin Li   ObjCMethodDecl *Method;
3954*67e74705SXin Li   llvm::SmallPtrSet<ObjCMethodDecl*, 4> Overridden;
3955*67e74705SXin Li   bool Recursive;
3956*67e74705SXin Li 
3957*67e74705SXin Li public:
OverrideSearch(Sema & S,ObjCMethodDecl * method)3958*67e74705SXin Li   OverrideSearch(Sema &S, ObjCMethodDecl *method) : S(S), Method(method) {
3959*67e74705SXin Li     Selector selector = method->getSelector();
3960*67e74705SXin Li 
3961*67e74705SXin Li     // Bypass this search if we've never seen an instance/class method
3962*67e74705SXin Li     // with this selector before.
3963*67e74705SXin Li     Sema::GlobalMethodPool::iterator it = S.MethodPool.find(selector);
3964*67e74705SXin Li     if (it == S.MethodPool.end()) {
3965*67e74705SXin Li       if (!S.getExternalSource()) return;
3966*67e74705SXin Li       S.ReadMethodPool(selector);
3967*67e74705SXin Li 
3968*67e74705SXin Li       it = S.MethodPool.find(selector);
3969*67e74705SXin Li       if (it == S.MethodPool.end())
3970*67e74705SXin Li         return;
3971*67e74705SXin Li     }
3972*67e74705SXin Li     ObjCMethodList &list =
3973*67e74705SXin Li       method->isInstanceMethod() ? it->second.first : it->second.second;
3974*67e74705SXin Li     if (!list.getMethod()) return;
3975*67e74705SXin Li 
3976*67e74705SXin Li     ObjCContainerDecl *container
3977*67e74705SXin Li       = cast<ObjCContainerDecl>(method->getDeclContext());
3978*67e74705SXin Li 
3979*67e74705SXin Li     // Prevent the search from reaching this container again.  This is
3980*67e74705SXin Li     // important with categories, which override methods from the
3981*67e74705SXin Li     // interface and each other.
3982*67e74705SXin Li     if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(container)) {
3983*67e74705SXin Li       searchFromContainer(container);
3984*67e74705SXin Li       if (ObjCInterfaceDecl *Interface = Category->getClassInterface())
3985*67e74705SXin Li         searchFromContainer(Interface);
3986*67e74705SXin Li     } else {
3987*67e74705SXin Li       searchFromContainer(container);
3988*67e74705SXin Li     }
3989*67e74705SXin Li   }
3990*67e74705SXin Li 
3991*67e74705SXin Li   typedef llvm::SmallPtrSetImpl<ObjCMethodDecl*>::iterator iterator;
begin() const3992*67e74705SXin Li   iterator begin() const { return Overridden.begin(); }
end() const3993*67e74705SXin Li   iterator end() const { return Overridden.end(); }
3994*67e74705SXin Li 
3995*67e74705SXin Li private:
searchFromContainer(ObjCContainerDecl * container)3996*67e74705SXin Li   void searchFromContainer(ObjCContainerDecl *container) {
3997*67e74705SXin Li     if (container->isInvalidDecl()) return;
3998*67e74705SXin Li 
3999*67e74705SXin Li     switch (container->getDeclKind()) {
4000*67e74705SXin Li #define OBJCCONTAINER(type, base) \
4001*67e74705SXin Li     case Decl::type: \
4002*67e74705SXin Li       searchFrom(cast<type##Decl>(container)); \
4003*67e74705SXin Li       break;
4004*67e74705SXin Li #define ABSTRACT_DECL(expansion)
4005*67e74705SXin Li #define DECL(type, base) \
4006*67e74705SXin Li     case Decl::type:
4007*67e74705SXin Li #include "clang/AST/DeclNodes.inc"
4008*67e74705SXin Li       llvm_unreachable("not an ObjC container!");
4009*67e74705SXin Li     }
4010*67e74705SXin Li   }
4011*67e74705SXin Li 
searchFrom(ObjCProtocolDecl * protocol)4012*67e74705SXin Li   void searchFrom(ObjCProtocolDecl *protocol) {
4013*67e74705SXin Li     if (!protocol->hasDefinition())
4014*67e74705SXin Li       return;
4015*67e74705SXin Li 
4016*67e74705SXin Li     // A method in a protocol declaration overrides declarations from
4017*67e74705SXin Li     // referenced ("parent") protocols.
4018*67e74705SXin Li     search(protocol->getReferencedProtocols());
4019*67e74705SXin Li   }
4020*67e74705SXin Li 
searchFrom(ObjCCategoryDecl * category)4021*67e74705SXin Li   void searchFrom(ObjCCategoryDecl *category) {
4022*67e74705SXin Li     // A method in a category declaration overrides declarations from
4023*67e74705SXin Li     // the main class and from protocols the category references.
4024*67e74705SXin Li     // The main class is handled in the constructor.
4025*67e74705SXin Li     search(category->getReferencedProtocols());
4026*67e74705SXin Li   }
4027*67e74705SXin Li 
searchFrom(ObjCCategoryImplDecl * impl)4028*67e74705SXin Li   void searchFrom(ObjCCategoryImplDecl *impl) {
4029*67e74705SXin Li     // A method in a category definition that has a category
4030*67e74705SXin Li     // declaration overrides declarations from the category
4031*67e74705SXin Li     // declaration.
4032*67e74705SXin Li     if (ObjCCategoryDecl *category = impl->getCategoryDecl()) {
4033*67e74705SXin Li       search(category);
4034*67e74705SXin Li       if (ObjCInterfaceDecl *Interface = category->getClassInterface())
4035*67e74705SXin Li         search(Interface);
4036*67e74705SXin Li 
4037*67e74705SXin Li     // Otherwise it overrides declarations from the class.
4038*67e74705SXin Li     } else if (ObjCInterfaceDecl *Interface = impl->getClassInterface()) {
4039*67e74705SXin Li       search(Interface);
4040*67e74705SXin Li     }
4041*67e74705SXin Li   }
4042*67e74705SXin Li 
searchFrom(ObjCInterfaceDecl * iface)4043*67e74705SXin Li   void searchFrom(ObjCInterfaceDecl *iface) {
4044*67e74705SXin Li     // A method in a class declaration overrides declarations from
4045*67e74705SXin Li     if (!iface->hasDefinition())
4046*67e74705SXin Li       return;
4047*67e74705SXin Li 
4048*67e74705SXin Li     //   - categories,
4049*67e74705SXin Li     for (auto *Cat : iface->known_categories())
4050*67e74705SXin Li       search(Cat);
4051*67e74705SXin Li 
4052*67e74705SXin Li     //   - the super class, and
4053*67e74705SXin Li     if (ObjCInterfaceDecl *super = iface->getSuperClass())
4054*67e74705SXin Li       search(super);
4055*67e74705SXin Li 
4056*67e74705SXin Li     //   - any referenced protocols.
4057*67e74705SXin Li     search(iface->getReferencedProtocols());
4058*67e74705SXin Li   }
4059*67e74705SXin Li 
searchFrom(ObjCImplementationDecl * impl)4060*67e74705SXin Li   void searchFrom(ObjCImplementationDecl *impl) {
4061*67e74705SXin Li     // A method in a class implementation overrides declarations from
4062*67e74705SXin Li     // the class interface.
4063*67e74705SXin Li     if (ObjCInterfaceDecl *Interface = impl->getClassInterface())
4064*67e74705SXin Li       search(Interface);
4065*67e74705SXin Li   }
4066*67e74705SXin Li 
search(const ObjCProtocolList & protocols)4067*67e74705SXin Li   void search(const ObjCProtocolList &protocols) {
4068*67e74705SXin Li     for (ObjCProtocolList::iterator i = protocols.begin(), e = protocols.end();
4069*67e74705SXin Li          i != e; ++i)
4070*67e74705SXin Li       search(*i);
4071*67e74705SXin Li   }
4072*67e74705SXin Li 
search(ObjCContainerDecl * container)4073*67e74705SXin Li   void search(ObjCContainerDecl *container) {
4074*67e74705SXin Li     // Check for a method in this container which matches this selector.
4075*67e74705SXin Li     ObjCMethodDecl *meth = container->getMethod(Method->getSelector(),
4076*67e74705SXin Li                                                 Method->isInstanceMethod(),
4077*67e74705SXin Li                                                 /*AllowHidden=*/true);
4078*67e74705SXin Li 
4079*67e74705SXin Li     // If we find one, record it and bail out.
4080*67e74705SXin Li     if (meth) {
4081*67e74705SXin Li       Overridden.insert(meth);
4082*67e74705SXin Li       return;
4083*67e74705SXin Li     }
4084*67e74705SXin Li 
4085*67e74705SXin Li     // Otherwise, search for methods that a hypothetical method here
4086*67e74705SXin Li     // would have overridden.
4087*67e74705SXin Li 
4088*67e74705SXin Li     // Note that we're now in a recursive case.
4089*67e74705SXin Li     Recursive = true;
4090*67e74705SXin Li 
4091*67e74705SXin Li     searchFromContainer(container);
4092*67e74705SXin Li   }
4093*67e74705SXin Li };
4094*67e74705SXin Li } // end anonymous namespace
4095*67e74705SXin Li 
CheckObjCMethodOverrides(ObjCMethodDecl * ObjCMethod,ObjCInterfaceDecl * CurrentClass,ResultTypeCompatibilityKind RTC)4096*67e74705SXin Li void Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod,
4097*67e74705SXin Li                                     ObjCInterfaceDecl *CurrentClass,
4098*67e74705SXin Li                                     ResultTypeCompatibilityKind RTC) {
4099*67e74705SXin Li   // Search for overridden methods and merge information down from them.
4100*67e74705SXin Li   OverrideSearch overrides(*this, ObjCMethod);
4101*67e74705SXin Li   // Keep track if the method overrides any method in the class's base classes,
4102*67e74705SXin Li   // its protocols, or its categories' protocols; we will keep that info
4103*67e74705SXin Li   // in the ObjCMethodDecl.
4104*67e74705SXin Li   // For this info, a method in an implementation is not considered as
4105*67e74705SXin Li   // overriding the same method in the interface or its categories.
4106*67e74705SXin Li   bool hasOverriddenMethodsInBaseOrProtocol = false;
4107*67e74705SXin Li   for (OverrideSearch::iterator
4108*67e74705SXin Li          i = overrides.begin(), e = overrides.end(); i != e; ++i) {
4109*67e74705SXin Li     ObjCMethodDecl *overridden = *i;
4110*67e74705SXin Li 
4111*67e74705SXin Li     if (!hasOverriddenMethodsInBaseOrProtocol) {
4112*67e74705SXin Li       if (isa<ObjCProtocolDecl>(overridden->getDeclContext()) ||
4113*67e74705SXin Li           CurrentClass != overridden->getClassInterface() ||
4114*67e74705SXin Li           overridden->isOverriding()) {
4115*67e74705SXin Li         hasOverriddenMethodsInBaseOrProtocol = true;
4116*67e74705SXin Li 
4117*67e74705SXin Li       } else if (isa<ObjCImplDecl>(ObjCMethod->getDeclContext())) {
4118*67e74705SXin Li         // OverrideSearch will return as "overridden" the same method in the
4119*67e74705SXin Li         // interface. For hasOverriddenMethodsInBaseOrProtocol, we need to
4120*67e74705SXin Li         // check whether a category of a base class introduced a method with the
4121*67e74705SXin Li         // same selector, after the interface method declaration.
4122*67e74705SXin Li         // To avoid unnecessary lookups in the majority of cases, we use the
4123*67e74705SXin Li         // extra info bits in GlobalMethodPool to check whether there were any
4124*67e74705SXin Li         // category methods with this selector.
4125*67e74705SXin Li         GlobalMethodPool::iterator It =
4126*67e74705SXin Li             MethodPool.find(ObjCMethod->getSelector());
4127*67e74705SXin Li         if (It != MethodPool.end()) {
4128*67e74705SXin Li           ObjCMethodList &List =
4129*67e74705SXin Li             ObjCMethod->isInstanceMethod()? It->second.first: It->second.second;
4130*67e74705SXin Li           unsigned CategCount = List.getBits();
4131*67e74705SXin Li           if (CategCount > 0) {
4132*67e74705SXin Li             // If the method is in a category we'll do lookup if there were at
4133*67e74705SXin Li             // least 2 category methods recorded, otherwise only one will do.
4134*67e74705SXin Li             if (CategCount > 1 ||
4135*67e74705SXin Li                 !isa<ObjCCategoryImplDecl>(overridden->getDeclContext())) {
4136*67e74705SXin Li               OverrideSearch overrides(*this, overridden);
4137*67e74705SXin Li               for (OverrideSearch::iterator
4138*67e74705SXin Li                      OI= overrides.begin(), OE= overrides.end(); OI!=OE; ++OI) {
4139*67e74705SXin Li                 ObjCMethodDecl *SuperOverridden = *OI;
4140*67e74705SXin Li                 if (isa<ObjCProtocolDecl>(SuperOverridden->getDeclContext()) ||
4141*67e74705SXin Li                     CurrentClass != SuperOverridden->getClassInterface()) {
4142*67e74705SXin Li                   hasOverriddenMethodsInBaseOrProtocol = true;
4143*67e74705SXin Li                   overridden->setOverriding(true);
4144*67e74705SXin Li                   break;
4145*67e74705SXin Li                 }
4146*67e74705SXin Li               }
4147*67e74705SXin Li             }
4148*67e74705SXin Li           }
4149*67e74705SXin Li         }
4150*67e74705SXin Li       }
4151*67e74705SXin Li     }
4152*67e74705SXin Li 
4153*67e74705SXin Li     // Propagate down the 'related result type' bit from overridden methods.
4154*67e74705SXin Li     if (RTC != Sema::RTC_Incompatible && overridden->hasRelatedResultType())
4155*67e74705SXin Li       ObjCMethod->SetRelatedResultType();
4156*67e74705SXin Li 
4157*67e74705SXin Li     // Then merge the declarations.
4158*67e74705SXin Li     mergeObjCMethodDecls(ObjCMethod, overridden);
4159*67e74705SXin Li 
4160*67e74705SXin Li     if (ObjCMethod->isImplicit() && overridden->isImplicit())
4161*67e74705SXin Li       continue; // Conflicting properties are detected elsewhere.
4162*67e74705SXin Li 
4163*67e74705SXin Li     // Check for overriding methods
4164*67e74705SXin Li     if (isa<ObjCInterfaceDecl>(ObjCMethod->getDeclContext()) ||
4165*67e74705SXin Li         isa<ObjCImplementationDecl>(ObjCMethod->getDeclContext()))
4166*67e74705SXin Li       CheckConflictingOverridingMethod(ObjCMethod, overridden,
4167*67e74705SXin Li               isa<ObjCProtocolDecl>(overridden->getDeclContext()));
4168*67e74705SXin Li 
4169*67e74705SXin Li     if (CurrentClass && overridden->getDeclContext() != CurrentClass &&
4170*67e74705SXin Li         isa<ObjCInterfaceDecl>(overridden->getDeclContext()) &&
4171*67e74705SXin Li         !overridden->isImplicit() /* not meant for properties */) {
4172*67e74705SXin Li       ObjCMethodDecl::param_iterator ParamI = ObjCMethod->param_begin(),
4173*67e74705SXin Li                                           E = ObjCMethod->param_end();
4174*67e74705SXin Li       ObjCMethodDecl::param_iterator PrevI = overridden->param_begin(),
4175*67e74705SXin Li                                      PrevE = overridden->param_end();
4176*67e74705SXin Li       for (; ParamI != E && PrevI != PrevE; ++ParamI, ++PrevI) {
4177*67e74705SXin Li         assert(PrevI != overridden->param_end() && "Param mismatch");
4178*67e74705SXin Li         QualType T1 = Context.getCanonicalType((*ParamI)->getType());
4179*67e74705SXin Li         QualType T2 = Context.getCanonicalType((*PrevI)->getType());
4180*67e74705SXin Li         // If type of argument of method in this class does not match its
4181*67e74705SXin Li         // respective argument type in the super class method, issue warning;
4182*67e74705SXin Li         if (!Context.typesAreCompatible(T1, T2)) {
4183*67e74705SXin Li           Diag((*ParamI)->getLocation(), diag::ext_typecheck_base_super)
4184*67e74705SXin Li             << T1 << T2;
4185*67e74705SXin Li           Diag(overridden->getLocation(), diag::note_previous_declaration);
4186*67e74705SXin Li           break;
4187*67e74705SXin Li         }
4188*67e74705SXin Li       }
4189*67e74705SXin Li     }
4190*67e74705SXin Li   }
4191*67e74705SXin Li 
4192*67e74705SXin Li   ObjCMethod->setOverriding(hasOverriddenMethodsInBaseOrProtocol);
4193*67e74705SXin Li }
4194*67e74705SXin Li 
4195*67e74705SXin Li /// Merge type nullability from for a redeclaration of the same entity,
4196*67e74705SXin Li /// producing the updated type of the redeclared entity.
mergeTypeNullabilityForRedecl(Sema & S,SourceLocation loc,QualType type,bool usesCSKeyword,SourceLocation prevLoc,QualType prevType,bool prevUsesCSKeyword)4197*67e74705SXin Li static QualType mergeTypeNullabilityForRedecl(Sema &S, SourceLocation loc,
4198*67e74705SXin Li                                               QualType type,
4199*67e74705SXin Li                                               bool usesCSKeyword,
4200*67e74705SXin Li                                               SourceLocation prevLoc,
4201*67e74705SXin Li                                               QualType prevType,
4202*67e74705SXin Li                                               bool prevUsesCSKeyword) {
4203*67e74705SXin Li   // Determine the nullability of both types.
4204*67e74705SXin Li   auto nullability = type->getNullability(S.Context);
4205*67e74705SXin Li   auto prevNullability = prevType->getNullability(S.Context);
4206*67e74705SXin Li 
4207*67e74705SXin Li   // Easy case: both have nullability.
4208*67e74705SXin Li   if (nullability.hasValue() == prevNullability.hasValue()) {
4209*67e74705SXin Li     // Neither has nullability; continue.
4210*67e74705SXin Li     if (!nullability)
4211*67e74705SXin Li       return type;
4212*67e74705SXin Li 
4213*67e74705SXin Li     // The nullabilities are equivalent; do nothing.
4214*67e74705SXin Li     if (*nullability == *prevNullability)
4215*67e74705SXin Li       return type;
4216*67e74705SXin Li 
4217*67e74705SXin Li     // Complain about mismatched nullability.
4218*67e74705SXin Li     S.Diag(loc, diag::err_nullability_conflicting)
4219*67e74705SXin Li       << DiagNullabilityKind(*nullability, usesCSKeyword)
4220*67e74705SXin Li       << DiagNullabilityKind(*prevNullability, prevUsesCSKeyword);
4221*67e74705SXin Li     return type;
4222*67e74705SXin Li   }
4223*67e74705SXin Li 
4224*67e74705SXin Li   // If it's the redeclaration that has nullability, don't change anything.
4225*67e74705SXin Li   if (nullability)
4226*67e74705SXin Li     return type;
4227*67e74705SXin Li 
4228*67e74705SXin Li   // Otherwise, provide the result with the same nullability.
4229*67e74705SXin Li   return S.Context.getAttributedType(
4230*67e74705SXin Li            AttributedType::getNullabilityAttrKind(*prevNullability),
4231*67e74705SXin Li            type, type);
4232*67e74705SXin Li }
4233*67e74705SXin Li 
4234*67e74705SXin Li /// Merge information from the declaration of a method in the \@interface
4235*67e74705SXin Li /// (or a category/extension) into the corresponding method in the
4236*67e74705SXin Li /// @implementation (for a class or category).
mergeInterfaceMethodToImpl(Sema & S,ObjCMethodDecl * method,ObjCMethodDecl * prevMethod)4237*67e74705SXin Li static void mergeInterfaceMethodToImpl(Sema &S,
4238*67e74705SXin Li                                        ObjCMethodDecl *method,
4239*67e74705SXin Li                                        ObjCMethodDecl *prevMethod) {
4240*67e74705SXin Li   // Merge the objc_requires_super attribute.
4241*67e74705SXin Li   if (prevMethod->hasAttr<ObjCRequiresSuperAttr>() &&
4242*67e74705SXin Li       !method->hasAttr<ObjCRequiresSuperAttr>()) {
4243*67e74705SXin Li     // merge the attribute into implementation.
4244*67e74705SXin Li     method->addAttr(
4245*67e74705SXin Li       ObjCRequiresSuperAttr::CreateImplicit(S.Context,
4246*67e74705SXin Li                                             method->getLocation()));
4247*67e74705SXin Li   }
4248*67e74705SXin Li 
4249*67e74705SXin Li   // Merge nullability of the result type.
4250*67e74705SXin Li   QualType newReturnType
4251*67e74705SXin Li     = mergeTypeNullabilityForRedecl(
4252*67e74705SXin Li         S, method->getReturnTypeSourceRange().getBegin(),
4253*67e74705SXin Li         method->getReturnType(),
4254*67e74705SXin Li         method->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability,
4255*67e74705SXin Li         prevMethod->getReturnTypeSourceRange().getBegin(),
4256*67e74705SXin Li         prevMethod->getReturnType(),
4257*67e74705SXin Li         prevMethod->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability);
4258*67e74705SXin Li   method->setReturnType(newReturnType);
4259*67e74705SXin Li 
4260*67e74705SXin Li   // Handle each of the parameters.
4261*67e74705SXin Li   unsigned numParams = method->param_size();
4262*67e74705SXin Li   unsigned numPrevParams = prevMethod->param_size();
4263*67e74705SXin Li   for (unsigned i = 0, n = std::min(numParams, numPrevParams); i != n; ++i) {
4264*67e74705SXin Li     ParmVarDecl *param = method->param_begin()[i];
4265*67e74705SXin Li     ParmVarDecl *prevParam = prevMethod->param_begin()[i];
4266*67e74705SXin Li 
4267*67e74705SXin Li     // Merge nullability.
4268*67e74705SXin Li     QualType newParamType
4269*67e74705SXin Li       = mergeTypeNullabilityForRedecl(
4270*67e74705SXin Li           S, param->getLocation(), param->getType(),
4271*67e74705SXin Li           param->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability,
4272*67e74705SXin Li           prevParam->getLocation(), prevParam->getType(),
4273*67e74705SXin Li           prevParam->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability);
4274*67e74705SXin Li     param->setType(newParamType);
4275*67e74705SXin Li   }
4276*67e74705SXin Li }
4277*67e74705SXin Li 
ActOnMethodDeclaration(Scope * S,SourceLocation MethodLoc,SourceLocation EndLoc,tok::TokenKind MethodType,ObjCDeclSpec & ReturnQT,ParsedType ReturnType,ArrayRef<SourceLocation> SelectorLocs,Selector Sel,ObjCArgInfo * ArgInfo,DeclaratorChunk::ParamInfo * CParamInfo,unsigned CNumArgs,AttributeList * AttrList,tok::ObjCKeywordKind MethodDeclKind,bool isVariadic,bool MethodDefinition)4278*67e74705SXin Li Decl *Sema::ActOnMethodDeclaration(
4279*67e74705SXin Li     Scope *S,
4280*67e74705SXin Li     SourceLocation MethodLoc, SourceLocation EndLoc,
4281*67e74705SXin Li     tok::TokenKind MethodType,
4282*67e74705SXin Li     ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
4283*67e74705SXin Li     ArrayRef<SourceLocation> SelectorLocs,
4284*67e74705SXin Li     Selector Sel,
4285*67e74705SXin Li     // optional arguments. The number of types/arguments is obtained
4286*67e74705SXin Li     // from the Sel.getNumArgs().
4287*67e74705SXin Li     ObjCArgInfo *ArgInfo,
4288*67e74705SXin Li     DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
4289*67e74705SXin Li     AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
4290*67e74705SXin Li     bool isVariadic, bool MethodDefinition) {
4291*67e74705SXin Li   // Make sure we can establish a context for the method.
4292*67e74705SXin Li   if (!CurContext->isObjCContainer()) {
4293*67e74705SXin Li     Diag(MethodLoc, diag::error_missing_method_context);
4294*67e74705SXin Li     return nullptr;
4295*67e74705SXin Li   }
4296*67e74705SXin Li   ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
4297*67e74705SXin Li   Decl *ClassDecl = cast<Decl>(OCD);
4298*67e74705SXin Li   QualType resultDeclType;
4299*67e74705SXin Li 
4300*67e74705SXin Li   bool HasRelatedResultType = false;
4301*67e74705SXin Li   TypeSourceInfo *ReturnTInfo = nullptr;
4302*67e74705SXin Li   if (ReturnType) {
4303*67e74705SXin Li     resultDeclType = GetTypeFromParser(ReturnType, &ReturnTInfo);
4304*67e74705SXin Li 
4305*67e74705SXin Li     if (CheckFunctionReturnType(resultDeclType, MethodLoc))
4306*67e74705SXin Li       return nullptr;
4307*67e74705SXin Li 
4308*67e74705SXin Li     QualType bareResultType = resultDeclType;
4309*67e74705SXin Li     (void)AttributedType::stripOuterNullability(bareResultType);
4310*67e74705SXin Li     HasRelatedResultType = (bareResultType == Context.getObjCInstanceType());
4311*67e74705SXin Li   } else { // get the type for "id".
4312*67e74705SXin Li     resultDeclType = Context.getObjCIdType();
4313*67e74705SXin Li     Diag(MethodLoc, diag::warn_missing_method_return_type)
4314*67e74705SXin Li       << FixItHint::CreateInsertion(SelectorLocs.front(), "(id)");
4315*67e74705SXin Li   }
4316*67e74705SXin Li 
4317*67e74705SXin Li   ObjCMethodDecl *ObjCMethod = ObjCMethodDecl::Create(
4318*67e74705SXin Li       Context, MethodLoc, EndLoc, Sel, resultDeclType, ReturnTInfo, CurContext,
4319*67e74705SXin Li       MethodType == tok::minus, isVariadic,
4320*67e74705SXin Li       /*isPropertyAccessor=*/false,
4321*67e74705SXin Li       /*isImplicitlyDeclared=*/false, /*isDefined=*/false,
4322*67e74705SXin Li       MethodDeclKind == tok::objc_optional ? ObjCMethodDecl::Optional
4323*67e74705SXin Li                                            : ObjCMethodDecl::Required,
4324*67e74705SXin Li       HasRelatedResultType);
4325*67e74705SXin Li 
4326*67e74705SXin Li   SmallVector<ParmVarDecl*, 16> Params;
4327*67e74705SXin Li 
4328*67e74705SXin Li   for (unsigned i = 0, e = Sel.getNumArgs(); i != e; ++i) {
4329*67e74705SXin Li     QualType ArgType;
4330*67e74705SXin Li     TypeSourceInfo *DI;
4331*67e74705SXin Li 
4332*67e74705SXin Li     if (!ArgInfo[i].Type) {
4333*67e74705SXin Li       ArgType = Context.getObjCIdType();
4334*67e74705SXin Li       DI = nullptr;
4335*67e74705SXin Li     } else {
4336*67e74705SXin Li       ArgType = GetTypeFromParser(ArgInfo[i].Type, &DI);
4337*67e74705SXin Li     }
4338*67e74705SXin Li 
4339*67e74705SXin Li     LookupResult R(*this, ArgInfo[i].Name, ArgInfo[i].NameLoc,
4340*67e74705SXin Li                    LookupOrdinaryName, ForRedeclaration);
4341*67e74705SXin Li     LookupName(R, S);
4342*67e74705SXin Li     if (R.isSingleResult()) {
4343*67e74705SXin Li       NamedDecl *PrevDecl = R.getFoundDecl();
4344*67e74705SXin Li       if (S->isDeclScope(PrevDecl)) {
4345*67e74705SXin Li         Diag(ArgInfo[i].NameLoc,
4346*67e74705SXin Li              (MethodDefinition ? diag::warn_method_param_redefinition
4347*67e74705SXin Li                                : diag::warn_method_param_declaration))
4348*67e74705SXin Li           << ArgInfo[i].Name;
4349*67e74705SXin Li         Diag(PrevDecl->getLocation(),
4350*67e74705SXin Li              diag::note_previous_declaration);
4351*67e74705SXin Li       }
4352*67e74705SXin Li     }
4353*67e74705SXin Li 
4354*67e74705SXin Li     SourceLocation StartLoc = DI
4355*67e74705SXin Li       ? DI->getTypeLoc().getBeginLoc()
4356*67e74705SXin Li       : ArgInfo[i].NameLoc;
4357*67e74705SXin Li 
4358*67e74705SXin Li     ParmVarDecl* Param = CheckParameter(ObjCMethod, StartLoc,
4359*67e74705SXin Li                                         ArgInfo[i].NameLoc, ArgInfo[i].Name,
4360*67e74705SXin Li                                         ArgType, DI, SC_None);
4361*67e74705SXin Li 
4362*67e74705SXin Li     Param->setObjCMethodScopeInfo(i);
4363*67e74705SXin Li 
4364*67e74705SXin Li     Param->setObjCDeclQualifier(
4365*67e74705SXin Li       CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier()));
4366*67e74705SXin Li 
4367*67e74705SXin Li     // Apply the attributes to the parameter.
4368*67e74705SXin Li     ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs);
4369*67e74705SXin Li 
4370*67e74705SXin Li     if (Param->hasAttr<BlocksAttr>()) {
4371*67e74705SXin Li       Diag(Param->getLocation(), diag::err_block_on_nonlocal);
4372*67e74705SXin Li       Param->setInvalidDecl();
4373*67e74705SXin Li     }
4374*67e74705SXin Li     S->AddDecl(Param);
4375*67e74705SXin Li     IdResolver.AddDecl(Param);
4376*67e74705SXin Li 
4377*67e74705SXin Li     Params.push_back(Param);
4378*67e74705SXin Li   }
4379*67e74705SXin Li 
4380*67e74705SXin Li   for (unsigned i = 0, e = CNumArgs; i != e; ++i) {
4381*67e74705SXin Li     ParmVarDecl *Param = cast<ParmVarDecl>(CParamInfo[i].Param);
4382*67e74705SXin Li     QualType ArgType = Param->getType();
4383*67e74705SXin Li     if (ArgType.isNull())
4384*67e74705SXin Li       ArgType = Context.getObjCIdType();
4385*67e74705SXin Li     else
4386*67e74705SXin Li       // Perform the default array/function conversions (C99 6.7.5.3p[7,8]).
4387*67e74705SXin Li       ArgType = Context.getAdjustedParameterType(ArgType);
4388*67e74705SXin Li 
4389*67e74705SXin Li     Param->setDeclContext(ObjCMethod);
4390*67e74705SXin Li     Params.push_back(Param);
4391*67e74705SXin Li   }
4392*67e74705SXin Li 
4393*67e74705SXin Li   ObjCMethod->setMethodParams(Context, Params, SelectorLocs);
4394*67e74705SXin Li   ObjCMethod->setObjCDeclQualifier(
4395*67e74705SXin Li     CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));
4396*67e74705SXin Li 
4397*67e74705SXin Li   if (AttrList)
4398*67e74705SXin Li     ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList);
4399*67e74705SXin Li 
4400*67e74705SXin Li   // Add the method now.
4401*67e74705SXin Li   const ObjCMethodDecl *PrevMethod = nullptr;
4402*67e74705SXin Li   if (ObjCImplDecl *ImpDecl = dyn_cast<ObjCImplDecl>(ClassDecl)) {
4403*67e74705SXin Li     if (MethodType == tok::minus) {
4404*67e74705SXin Li       PrevMethod = ImpDecl->getInstanceMethod(Sel);
4405*67e74705SXin Li       ImpDecl->addInstanceMethod(ObjCMethod);
4406*67e74705SXin Li     } else {
4407*67e74705SXin Li       PrevMethod = ImpDecl->getClassMethod(Sel);
4408*67e74705SXin Li       ImpDecl->addClassMethod(ObjCMethod);
4409*67e74705SXin Li     }
4410*67e74705SXin Li 
4411*67e74705SXin Li     // Merge information from the @interface declaration into the
4412*67e74705SXin Li     // @implementation.
4413*67e74705SXin Li     if (ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface()) {
4414*67e74705SXin Li       if (auto *IMD = IDecl->lookupMethod(ObjCMethod->getSelector(),
4415*67e74705SXin Li                                           ObjCMethod->isInstanceMethod())) {
4416*67e74705SXin Li         mergeInterfaceMethodToImpl(*this, ObjCMethod, IMD);
4417*67e74705SXin Li 
4418*67e74705SXin Li         // Warn about defining -dealloc in a category.
4419*67e74705SXin Li         if (isa<ObjCCategoryImplDecl>(ImpDecl) && IMD->isOverriding() &&
4420*67e74705SXin Li             ObjCMethod->getSelector().getMethodFamily() == OMF_dealloc) {
4421*67e74705SXin Li           Diag(ObjCMethod->getLocation(), diag::warn_dealloc_in_category)
4422*67e74705SXin Li             << ObjCMethod->getDeclName();
4423*67e74705SXin Li         }
4424*67e74705SXin Li       }
4425*67e74705SXin Li     }
4426*67e74705SXin Li   } else {
4427*67e74705SXin Li     cast<DeclContext>(ClassDecl)->addDecl(ObjCMethod);
4428*67e74705SXin Li   }
4429*67e74705SXin Li 
4430*67e74705SXin Li   if (PrevMethod) {
4431*67e74705SXin Li     // You can never have two method definitions with the same name.
4432*67e74705SXin Li     Diag(ObjCMethod->getLocation(), diag::err_duplicate_method_decl)
4433*67e74705SXin Li       << ObjCMethod->getDeclName();
4434*67e74705SXin Li     Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
4435*67e74705SXin Li     ObjCMethod->setInvalidDecl();
4436*67e74705SXin Li     return ObjCMethod;
4437*67e74705SXin Li   }
4438*67e74705SXin Li 
4439*67e74705SXin Li   // If this Objective-C method does not have a related result type, but we
4440*67e74705SXin Li   // are allowed to infer related result types, try to do so based on the
4441*67e74705SXin Li   // method family.
4442*67e74705SXin Li   ObjCInterfaceDecl *CurrentClass = dyn_cast<ObjCInterfaceDecl>(ClassDecl);
4443*67e74705SXin Li   if (!CurrentClass) {
4444*67e74705SXin Li     if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(ClassDecl))
4445*67e74705SXin Li       CurrentClass = Cat->getClassInterface();
4446*67e74705SXin Li     else if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(ClassDecl))
4447*67e74705SXin Li       CurrentClass = Impl->getClassInterface();
4448*67e74705SXin Li     else if (ObjCCategoryImplDecl *CatImpl
4449*67e74705SXin Li                                    = dyn_cast<ObjCCategoryImplDecl>(ClassDecl))
4450*67e74705SXin Li       CurrentClass = CatImpl->getClassInterface();
4451*67e74705SXin Li   }
4452*67e74705SXin Li 
4453*67e74705SXin Li   ResultTypeCompatibilityKind RTC
4454*67e74705SXin Li     = CheckRelatedResultTypeCompatibility(*this, ObjCMethod, CurrentClass);
4455*67e74705SXin Li 
4456*67e74705SXin Li   CheckObjCMethodOverrides(ObjCMethod, CurrentClass, RTC);
4457*67e74705SXin Li 
4458*67e74705SXin Li   bool ARCError = false;
4459*67e74705SXin Li   if (getLangOpts().ObjCAutoRefCount)
4460*67e74705SXin Li     ARCError = CheckARCMethodDecl(ObjCMethod);
4461*67e74705SXin Li 
4462*67e74705SXin Li   // Infer the related result type when possible.
4463*67e74705SXin Li   if (!ARCError && RTC == Sema::RTC_Compatible &&
4464*67e74705SXin Li       !ObjCMethod->hasRelatedResultType() &&
4465*67e74705SXin Li       LangOpts.ObjCInferRelatedResultType) {
4466*67e74705SXin Li     bool InferRelatedResultType = false;
4467*67e74705SXin Li     switch (ObjCMethod->getMethodFamily()) {
4468*67e74705SXin Li     case OMF_None:
4469*67e74705SXin Li     case OMF_copy:
4470*67e74705SXin Li     case OMF_dealloc:
4471*67e74705SXin Li     case OMF_finalize:
4472*67e74705SXin Li     case OMF_mutableCopy:
4473*67e74705SXin Li     case OMF_release:
4474*67e74705SXin Li     case OMF_retainCount:
4475*67e74705SXin Li     case OMF_initialize:
4476*67e74705SXin Li     case OMF_performSelector:
4477*67e74705SXin Li       break;
4478*67e74705SXin Li 
4479*67e74705SXin Li     case OMF_alloc:
4480*67e74705SXin Li     case OMF_new:
4481*67e74705SXin Li         InferRelatedResultType = ObjCMethod->isClassMethod();
4482*67e74705SXin Li       break;
4483*67e74705SXin Li 
4484*67e74705SXin Li     case OMF_init:
4485*67e74705SXin Li     case OMF_autorelease:
4486*67e74705SXin Li     case OMF_retain:
4487*67e74705SXin Li     case OMF_self:
4488*67e74705SXin Li       InferRelatedResultType = ObjCMethod->isInstanceMethod();
4489*67e74705SXin Li       break;
4490*67e74705SXin Li     }
4491*67e74705SXin Li 
4492*67e74705SXin Li     if (InferRelatedResultType &&
4493*67e74705SXin Li         !ObjCMethod->getReturnType()->isObjCIndependentClassType())
4494*67e74705SXin Li       ObjCMethod->SetRelatedResultType();
4495*67e74705SXin Li   }
4496*67e74705SXin Li 
4497*67e74705SXin Li   ActOnDocumentableDecl(ObjCMethod);
4498*67e74705SXin Li 
4499*67e74705SXin Li   return ObjCMethod;
4500*67e74705SXin Li }
4501*67e74705SXin Li 
CheckObjCDeclScope(Decl * D)4502*67e74705SXin Li bool Sema::CheckObjCDeclScope(Decl *D) {
4503*67e74705SXin Li   // Following is also an error. But it is caused by a missing @end
4504*67e74705SXin Li   // and diagnostic is issued elsewhere.
4505*67e74705SXin Li   if (isa<ObjCContainerDecl>(CurContext->getRedeclContext()))
4506*67e74705SXin Li     return false;
4507*67e74705SXin Li 
4508*67e74705SXin Li   // If we switched context to translation unit while we are still lexically in
4509*67e74705SXin Li   // an objc container, it means the parser missed emitting an error.
4510*67e74705SXin Li   if (isa<TranslationUnitDecl>(getCurLexicalContext()->getRedeclContext()))
4511*67e74705SXin Li     return false;
4512*67e74705SXin Li 
4513*67e74705SXin Li   Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
4514*67e74705SXin Li   D->setInvalidDecl();
4515*67e74705SXin Li 
4516*67e74705SXin Li   return true;
4517*67e74705SXin Li }
4518*67e74705SXin Li 
4519*67e74705SXin Li /// Called whenever \@defs(ClassName) is encountered in the source.  Inserts the
4520*67e74705SXin Li /// instance variables of ClassName into Decls.
ActOnDefs(Scope * S,Decl * TagD,SourceLocation DeclStart,IdentifierInfo * ClassName,SmallVectorImpl<Decl * > & Decls)4521*67e74705SXin Li void Sema::ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart,
4522*67e74705SXin Li                      IdentifierInfo *ClassName,
4523*67e74705SXin Li                      SmallVectorImpl<Decl*> &Decls) {
4524*67e74705SXin Li   // Check that ClassName is a valid class
4525*67e74705SXin Li   ObjCInterfaceDecl *Class = getObjCInterfaceDecl(ClassName, DeclStart);
4526*67e74705SXin Li   if (!Class) {
4527*67e74705SXin Li     Diag(DeclStart, diag::err_undef_interface) << ClassName;
4528*67e74705SXin Li     return;
4529*67e74705SXin Li   }
4530*67e74705SXin Li   if (LangOpts.ObjCRuntime.isNonFragile()) {
4531*67e74705SXin Li     Diag(DeclStart, diag::err_atdef_nonfragile_interface);
4532*67e74705SXin Li     return;
4533*67e74705SXin Li   }
4534*67e74705SXin Li 
4535*67e74705SXin Li   // Collect the instance variables
4536*67e74705SXin Li   SmallVector<const ObjCIvarDecl*, 32> Ivars;
4537*67e74705SXin Li   Context.DeepCollectObjCIvars(Class, true, Ivars);
4538*67e74705SXin Li   // For each ivar, create a fresh ObjCAtDefsFieldDecl.
4539*67e74705SXin Li   for (unsigned i = 0; i < Ivars.size(); i++) {
4540*67e74705SXin Li     const FieldDecl* ID = cast<FieldDecl>(Ivars[i]);
4541*67e74705SXin Li     RecordDecl *Record = dyn_cast<RecordDecl>(TagD);
4542*67e74705SXin Li     Decl *FD = ObjCAtDefsFieldDecl::Create(Context, Record,
4543*67e74705SXin Li                                            /*FIXME: StartL=*/ID->getLocation(),
4544*67e74705SXin Li                                            ID->getLocation(),
4545*67e74705SXin Li                                            ID->getIdentifier(), ID->getType(),
4546*67e74705SXin Li                                            ID->getBitWidth());
4547*67e74705SXin Li     Decls.push_back(FD);
4548*67e74705SXin Li   }
4549*67e74705SXin Li 
4550*67e74705SXin Li   // Introduce all of these fields into the appropriate scope.
4551*67e74705SXin Li   for (SmallVectorImpl<Decl*>::iterator D = Decls.begin();
4552*67e74705SXin Li        D != Decls.end(); ++D) {
4553*67e74705SXin Li     FieldDecl *FD = cast<FieldDecl>(*D);
4554*67e74705SXin Li     if (getLangOpts().CPlusPlus)
4555*67e74705SXin Li       PushOnScopeChains(cast<FieldDecl>(FD), S);
4556*67e74705SXin Li     else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD))
4557*67e74705SXin Li       Record->addDecl(FD);
4558*67e74705SXin Li   }
4559*67e74705SXin Li }
4560*67e74705SXin Li 
4561*67e74705SXin Li /// \brief Build a type-check a new Objective-C exception variable declaration.
BuildObjCExceptionDecl(TypeSourceInfo * TInfo,QualType T,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id,bool Invalid)4562*67e74705SXin Li VarDecl *Sema::BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType T,
4563*67e74705SXin Li                                       SourceLocation StartLoc,
4564*67e74705SXin Li                                       SourceLocation IdLoc,
4565*67e74705SXin Li                                       IdentifierInfo *Id,
4566*67e74705SXin Li                                       bool Invalid) {
4567*67e74705SXin Li   // ISO/IEC TR 18037 S6.7.3: "The type of an object with automatic storage
4568*67e74705SXin Li   // duration shall not be qualified by an address-space qualifier."
4569*67e74705SXin Li   // Since all parameters have automatic store duration, they can not have
4570*67e74705SXin Li   // an address space.
4571*67e74705SXin Li   if (T.getAddressSpace() != 0) {
4572*67e74705SXin Li     Diag(IdLoc, diag::err_arg_with_address_space);
4573*67e74705SXin Li     Invalid = true;
4574*67e74705SXin Li   }
4575*67e74705SXin Li 
4576*67e74705SXin Li   // An @catch parameter must be an unqualified object pointer type;
4577*67e74705SXin Li   // FIXME: Recover from "NSObject foo" by inserting the * in "NSObject *foo"?
4578*67e74705SXin Li   if (Invalid) {
4579*67e74705SXin Li     // Don't do any further checking.
4580*67e74705SXin Li   } else if (T->isDependentType()) {
4581*67e74705SXin Li     // Okay: we don't know what this type will instantiate to.
4582*67e74705SXin Li   } else if (!T->isObjCObjectPointerType()) {
4583*67e74705SXin Li     Invalid = true;
4584*67e74705SXin Li     Diag(IdLoc ,diag::err_catch_param_not_objc_type);
4585*67e74705SXin Li   } else if (T->isObjCQualifiedIdType()) {
4586*67e74705SXin Li     Invalid = true;
4587*67e74705SXin Li     Diag(IdLoc, diag::err_illegal_qualifiers_on_catch_parm);
4588*67e74705SXin Li   }
4589*67e74705SXin Li 
4590*67e74705SXin Li   VarDecl *New = VarDecl::Create(Context, CurContext, StartLoc, IdLoc, Id,
4591*67e74705SXin Li                                  T, TInfo, SC_None);
4592*67e74705SXin Li   New->setExceptionVariable(true);
4593*67e74705SXin Li 
4594*67e74705SXin Li   // In ARC, infer 'retaining' for variables of retainable type.
4595*67e74705SXin Li   if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(New))
4596*67e74705SXin Li     Invalid = true;
4597*67e74705SXin Li 
4598*67e74705SXin Li   if (Invalid)
4599*67e74705SXin Li     New->setInvalidDecl();
4600*67e74705SXin Li   return New;
4601*67e74705SXin Li }
4602*67e74705SXin Li 
ActOnObjCExceptionDecl(Scope * S,Declarator & D)4603*67e74705SXin Li Decl *Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
4604*67e74705SXin Li   const DeclSpec &DS = D.getDeclSpec();
4605*67e74705SXin Li 
4606*67e74705SXin Li   // We allow the "register" storage class on exception variables because
4607*67e74705SXin Li   // GCC did, but we drop it completely. Any other storage class is an error.
4608*67e74705SXin Li   if (DS.getStorageClassSpec() == DeclSpec::SCS_register) {
4609*67e74705SXin Li     Diag(DS.getStorageClassSpecLoc(), diag::warn_register_objc_catch_parm)
4610*67e74705SXin Li       << FixItHint::CreateRemoval(SourceRange(DS.getStorageClassSpecLoc()));
4611*67e74705SXin Li   } else if (DeclSpec::SCS SCS = DS.getStorageClassSpec()) {
4612*67e74705SXin Li     Diag(DS.getStorageClassSpecLoc(), diag::err_storage_spec_on_catch_parm)
4613*67e74705SXin Li       << DeclSpec::getSpecifierName(SCS);
4614*67e74705SXin Li   }
4615*67e74705SXin Li   if (DS.isInlineSpecified())
4616*67e74705SXin Li     Diag(DS.getInlineSpecLoc(), diag::err_inline_non_function)
4617*67e74705SXin Li         << getLangOpts().CPlusPlus1z;
4618*67e74705SXin Li   if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec())
4619*67e74705SXin Li     Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
4620*67e74705SXin Li          diag::err_invalid_thread)
4621*67e74705SXin Li      << DeclSpec::getSpecifierName(TSCS);
4622*67e74705SXin Li   D.getMutableDeclSpec().ClearStorageClassSpecs();
4623*67e74705SXin Li 
4624*67e74705SXin Li   DiagnoseFunctionSpecifiers(D.getDeclSpec());
4625*67e74705SXin Li 
4626*67e74705SXin Li   // Check that there are no default arguments inside the type of this
4627*67e74705SXin Li   // exception object (C++ only).
4628*67e74705SXin Li   if (getLangOpts().CPlusPlus)
4629*67e74705SXin Li     CheckExtraCXXDefaultArguments(D);
4630*67e74705SXin Li 
4631*67e74705SXin Li   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
4632*67e74705SXin Li   QualType ExceptionType = TInfo->getType();
4633*67e74705SXin Li 
4634*67e74705SXin Li   VarDecl *New = BuildObjCExceptionDecl(TInfo, ExceptionType,
4635*67e74705SXin Li                                         D.getSourceRange().getBegin(),
4636*67e74705SXin Li                                         D.getIdentifierLoc(),
4637*67e74705SXin Li                                         D.getIdentifier(),
4638*67e74705SXin Li                                         D.isInvalidType());
4639*67e74705SXin Li 
4640*67e74705SXin Li   // Parameter declarators cannot be qualified (C++ [dcl.meaning]p1).
4641*67e74705SXin Li   if (D.getCXXScopeSpec().isSet()) {
4642*67e74705SXin Li     Diag(D.getIdentifierLoc(), diag::err_qualified_objc_catch_parm)
4643*67e74705SXin Li       << D.getCXXScopeSpec().getRange();
4644*67e74705SXin Li     New->setInvalidDecl();
4645*67e74705SXin Li   }
4646*67e74705SXin Li 
4647*67e74705SXin Li   // Add the parameter declaration into this scope.
4648*67e74705SXin Li   S->AddDecl(New);
4649*67e74705SXin Li   if (D.getIdentifier())
4650*67e74705SXin Li     IdResolver.AddDecl(New);
4651*67e74705SXin Li 
4652*67e74705SXin Li   ProcessDeclAttributes(S, New, D);
4653*67e74705SXin Li 
4654*67e74705SXin Li   if (New->hasAttr<BlocksAttr>())
4655*67e74705SXin Li     Diag(New->getLocation(), diag::err_block_on_nonlocal);
4656*67e74705SXin Li   return New;
4657*67e74705SXin Li }
4658*67e74705SXin Li 
4659*67e74705SXin Li /// CollectIvarsToConstructOrDestruct - Collect those ivars which require
4660*67e74705SXin Li /// initialization.
CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl * OI,SmallVectorImpl<ObjCIvarDecl * > & Ivars)4661*67e74705SXin Li void Sema::CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI,
4662*67e74705SXin Li                                 SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
4663*67e74705SXin Li   for (ObjCIvarDecl *Iv = OI->all_declared_ivar_begin(); Iv;
4664*67e74705SXin Li        Iv= Iv->getNextIvar()) {
4665*67e74705SXin Li     QualType QT = Context.getBaseElementType(Iv->getType());
4666*67e74705SXin Li     if (QT->isRecordType())
4667*67e74705SXin Li       Ivars.push_back(Iv);
4668*67e74705SXin Li   }
4669*67e74705SXin Li }
4670*67e74705SXin Li 
DiagnoseUseOfUnimplementedSelectors()4671*67e74705SXin Li void Sema::DiagnoseUseOfUnimplementedSelectors() {
4672*67e74705SXin Li   // Load referenced selectors from the external source.
4673*67e74705SXin Li   if (ExternalSource) {
4674*67e74705SXin Li     SmallVector<std::pair<Selector, SourceLocation>, 4> Sels;
4675*67e74705SXin Li     ExternalSource->ReadReferencedSelectors(Sels);
4676*67e74705SXin Li     for (unsigned I = 0, N = Sels.size(); I != N; ++I)
4677*67e74705SXin Li       ReferencedSelectors[Sels[I].first] = Sels[I].second;
4678*67e74705SXin Li   }
4679*67e74705SXin Li 
4680*67e74705SXin Li   // Warning will be issued only when selector table is
4681*67e74705SXin Li   // generated (which means there is at lease one implementation
4682*67e74705SXin Li   // in the TU). This is to match gcc's behavior.
4683*67e74705SXin Li   if (ReferencedSelectors.empty() ||
4684*67e74705SXin Li       !Context.AnyObjCImplementation())
4685*67e74705SXin Li     return;
4686*67e74705SXin Li   for (auto &SelectorAndLocation : ReferencedSelectors) {
4687*67e74705SXin Li     Selector Sel = SelectorAndLocation.first;
4688*67e74705SXin Li     SourceLocation Loc = SelectorAndLocation.second;
4689*67e74705SXin Li     if (!LookupImplementedMethodInGlobalPool(Sel))
4690*67e74705SXin Li       Diag(Loc, diag::warn_unimplemented_selector) << Sel;
4691*67e74705SXin Li   }
4692*67e74705SXin Li }
4693*67e74705SXin Li 
4694*67e74705SXin Li ObjCIvarDecl *
GetIvarBackingPropertyAccessor(const ObjCMethodDecl * Method,const ObjCPropertyDecl * & PDecl) const4695*67e74705SXin Li Sema::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method,
4696*67e74705SXin Li                                      const ObjCPropertyDecl *&PDecl) const {
4697*67e74705SXin Li   if (Method->isClassMethod())
4698*67e74705SXin Li     return nullptr;
4699*67e74705SXin Li   const ObjCInterfaceDecl *IDecl = Method->getClassInterface();
4700*67e74705SXin Li   if (!IDecl)
4701*67e74705SXin Li     return nullptr;
4702*67e74705SXin Li   Method = IDecl->lookupMethod(Method->getSelector(), /*isInstance=*/true,
4703*67e74705SXin Li                                /*shallowCategoryLookup=*/false,
4704*67e74705SXin Li                                /*followSuper=*/false);
4705*67e74705SXin Li   if (!Method || !Method->isPropertyAccessor())
4706*67e74705SXin Li     return nullptr;
4707*67e74705SXin Li   if ((PDecl = Method->findPropertyDecl()))
4708*67e74705SXin Li     if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl()) {
4709*67e74705SXin Li       // property backing ivar must belong to property's class
4710*67e74705SXin Li       // or be a private ivar in class's implementation.
4711*67e74705SXin Li       // FIXME. fix the const-ness issue.
4712*67e74705SXin Li       IV = const_cast<ObjCInterfaceDecl *>(IDecl)->lookupInstanceVariable(
4713*67e74705SXin Li                                                         IV->getIdentifier());
4714*67e74705SXin Li       return IV;
4715*67e74705SXin Li     }
4716*67e74705SXin Li   return nullptr;
4717*67e74705SXin Li }
4718*67e74705SXin Li 
4719*67e74705SXin Li namespace {
4720*67e74705SXin Li   /// Used by Sema::DiagnoseUnusedBackingIvarInAccessor to check if a property
4721*67e74705SXin Li   /// accessor references the backing ivar.
4722*67e74705SXin Li   class UnusedBackingIvarChecker :
4723*67e74705SXin Li       public RecursiveASTVisitor<UnusedBackingIvarChecker> {
4724*67e74705SXin Li   public:
4725*67e74705SXin Li     Sema &S;
4726*67e74705SXin Li     const ObjCMethodDecl *Method;
4727*67e74705SXin Li     const ObjCIvarDecl *IvarD;
4728*67e74705SXin Li     bool AccessedIvar;
4729*67e74705SXin Li     bool InvokedSelfMethod;
4730*67e74705SXin Li 
UnusedBackingIvarChecker(Sema & S,const ObjCMethodDecl * Method,const ObjCIvarDecl * IvarD)4731*67e74705SXin Li     UnusedBackingIvarChecker(Sema &S, const ObjCMethodDecl *Method,
4732*67e74705SXin Li                              const ObjCIvarDecl *IvarD)
4733*67e74705SXin Li       : S(S), Method(Method), IvarD(IvarD),
4734*67e74705SXin Li         AccessedIvar(false), InvokedSelfMethod(false) {
4735*67e74705SXin Li       assert(IvarD);
4736*67e74705SXin Li     }
4737*67e74705SXin Li 
VisitObjCIvarRefExpr(ObjCIvarRefExpr * E)4738*67e74705SXin Li     bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
4739*67e74705SXin Li       if (E->getDecl() == IvarD) {
4740*67e74705SXin Li         AccessedIvar = true;
4741*67e74705SXin Li         return false;
4742*67e74705SXin Li       }
4743*67e74705SXin Li       return true;
4744*67e74705SXin Li     }
4745*67e74705SXin Li 
VisitObjCMessageExpr(ObjCMessageExpr * E)4746*67e74705SXin Li     bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
4747*67e74705SXin Li       if (E->getReceiverKind() == ObjCMessageExpr::Instance &&
4748*67e74705SXin Li           S.isSelfExpr(E->getInstanceReceiver(), Method)) {
4749*67e74705SXin Li         InvokedSelfMethod = true;
4750*67e74705SXin Li       }
4751*67e74705SXin Li       return true;
4752*67e74705SXin Li     }
4753*67e74705SXin Li   };
4754*67e74705SXin Li } // end anonymous namespace
4755*67e74705SXin Li 
DiagnoseUnusedBackingIvarInAccessor(Scope * S,const ObjCImplementationDecl * ImplD)4756*67e74705SXin Li void Sema::DiagnoseUnusedBackingIvarInAccessor(Scope *S,
4757*67e74705SXin Li                                           const ObjCImplementationDecl *ImplD) {
4758*67e74705SXin Li   if (S->hasUnrecoverableErrorOccurred())
4759*67e74705SXin Li     return;
4760*67e74705SXin Li 
4761*67e74705SXin Li   for (const auto *CurMethod : ImplD->instance_methods()) {
4762*67e74705SXin Li     unsigned DIAG = diag::warn_unused_property_backing_ivar;
4763*67e74705SXin Li     SourceLocation Loc = CurMethod->getLocation();
4764*67e74705SXin Li     if (Diags.isIgnored(DIAG, Loc))
4765*67e74705SXin Li       continue;
4766*67e74705SXin Li 
4767*67e74705SXin Li     const ObjCPropertyDecl *PDecl;
4768*67e74705SXin Li     const ObjCIvarDecl *IV = GetIvarBackingPropertyAccessor(CurMethod, PDecl);
4769*67e74705SXin Li     if (!IV)
4770*67e74705SXin Li       continue;
4771*67e74705SXin Li 
4772*67e74705SXin Li     UnusedBackingIvarChecker Checker(*this, CurMethod, IV);
4773*67e74705SXin Li     Checker.TraverseStmt(CurMethod->getBody());
4774*67e74705SXin Li     if (Checker.AccessedIvar)
4775*67e74705SXin Li       continue;
4776*67e74705SXin Li 
4777*67e74705SXin Li     // Do not issue this warning if backing ivar is used somewhere and accessor
4778*67e74705SXin Li     // implementation makes a self call. This is to prevent false positive in
4779*67e74705SXin Li     // cases where the ivar is accessed by another method that the accessor
4780*67e74705SXin Li     // delegates to.
4781*67e74705SXin Li     if (!IV->isReferenced() || !Checker.InvokedSelfMethod) {
4782*67e74705SXin Li       Diag(Loc, DIAG) << IV;
4783*67e74705SXin Li       Diag(PDecl->getLocation(), diag::note_property_declare);
4784*67e74705SXin Li     }
4785*67e74705SXin Li   }
4786*67e74705SXin Li }
4787