1193326Sed//===--- SemaDeclObjC.cpp - Semantic Analysis for ObjC Declarations -------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed//  This file implements semantic analysis for Objective C declarations.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14212904Sdim#include "clang/Sema/SemaInternal.h"
15224145Sdim#include "clang/AST/ASTConsumer.h"
16249423Sdim#include "clang/AST/ASTContext.h"
17249423Sdim#include "clang/AST/ASTMutationListener.h"
18249423Sdim#include "clang/AST/DeclObjC.h"
19193326Sed#include "clang/AST/Expr.h"
20224145Sdim#include "clang/AST/ExprObjC.h"
21224145Sdim#include "clang/Basic/SourceManager.h"
22249423Sdim#include "clang/Lex/Preprocessor.h"
23212904Sdim#include "clang/Sema/DeclSpec.h"
24249423Sdim#include "clang/Sema/ExternalSemaSource.h"
25249423Sdim#include "clang/Sema/Lookup.h"
26249423Sdim#include "clang/Sema/Scope.h"
27249423Sdim#include "clang/Sema/ScopeInfo.h"
28212904Sdim#include "llvm/ADT/DenseSet.h"
29212904Sdim
30193326Sedusing namespace clang;
31193326Sed
32224145Sdim/// Check whether the given method, which must be in the 'init'
33224145Sdim/// family, is a valid member of that family.
34224145Sdim///
35224145Sdim/// \param receiverTypeIfCall - if null, check this as if declaring it;
36224145Sdim///   if non-null, check this as if making a call to it with the given
37224145Sdim///   receiver type
38224145Sdim///
39224145Sdim/// \return true to indicate that there was an error and appropriate
40224145Sdim///   actions were taken
41224145Sdimbool Sema::checkInitMethod(ObjCMethodDecl *method,
42224145Sdim                           QualType receiverTypeIfCall) {
43224145Sdim  if (method->isInvalidDecl()) return true;
44224145Sdim
45224145Sdim  // This castAs is safe: methods that don't return an object
46224145Sdim  // pointer won't be inferred as inits and will reject an explicit
47224145Sdim  // objc_method_family(init).
48224145Sdim
49224145Sdim  // We ignore protocols here.  Should we?  What about Class?
50224145Sdim
51224145Sdim  const ObjCObjectType *result = method->getResultType()
52224145Sdim    ->castAs<ObjCObjectPointerType>()->getObjectType();
53224145Sdim
54224145Sdim  if (result->isObjCId()) {
55224145Sdim    return false;
56224145Sdim  } else if (result->isObjCClass()) {
57224145Sdim    // fall through: always an error
58224145Sdim  } else {
59224145Sdim    ObjCInterfaceDecl *resultClass = result->getInterface();
60224145Sdim    assert(resultClass && "unexpected object type!");
61224145Sdim
62224145Sdim    // It's okay for the result type to still be a forward declaration
63224145Sdim    // if we're checking an interface declaration.
64234353Sdim    if (!resultClass->hasDefinition()) {
65224145Sdim      if (receiverTypeIfCall.isNull() &&
66224145Sdim          !isa<ObjCImplementationDecl>(method->getDeclContext()))
67224145Sdim        return false;
68224145Sdim
69224145Sdim    // Otherwise, we try to compare class types.
70224145Sdim    } else {
71224145Sdim      // If this method was declared in a protocol, we can't check
72224145Sdim      // anything unless we have a receiver type that's an interface.
73224145Sdim      const ObjCInterfaceDecl *receiverClass = 0;
74224145Sdim      if (isa<ObjCProtocolDecl>(method->getDeclContext())) {
75224145Sdim        if (receiverTypeIfCall.isNull())
76224145Sdim          return false;
77224145Sdim
78224145Sdim        receiverClass = receiverTypeIfCall->castAs<ObjCObjectPointerType>()
79224145Sdim          ->getInterfaceDecl();
80224145Sdim
81224145Sdim        // This can be null for calls to e.g. id<Foo>.
82224145Sdim        if (!receiverClass) return false;
83224145Sdim      } else {
84224145Sdim        receiverClass = method->getClassInterface();
85224145Sdim        assert(receiverClass && "method not associated with a class!");
86224145Sdim      }
87224145Sdim
88224145Sdim      // If either class is a subclass of the other, it's fine.
89224145Sdim      if (receiverClass->isSuperClassOf(resultClass) ||
90224145Sdim          resultClass->isSuperClassOf(receiverClass))
91224145Sdim        return false;
92224145Sdim    }
93224145Sdim  }
94224145Sdim
95224145Sdim  SourceLocation loc = method->getLocation();
96224145Sdim
97224145Sdim  // If we're in a system header, and this is not a call, just make
98224145Sdim  // the method unusable.
99224145Sdim  if (receiverTypeIfCall.isNull() && getSourceManager().isInSystemHeader(loc)) {
100224145Sdim    method->addAttr(new (Context) UnavailableAttr(loc, Context,
101224145Sdim                "init method returns a type unrelated to its receiver type"));
102224145Sdim    return true;
103224145Sdim  }
104224145Sdim
105224145Sdim  // Otherwise, it's an error.
106224145Sdim  Diag(loc, diag::err_arc_init_method_unrelated_result_type);
107224145Sdim  method->setInvalidDecl();
108224145Sdim  return true;
109224145Sdim}
110224145Sdim
111226633Sdimvoid Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod,
112249423Sdim                                   const ObjCMethodDecl *Overridden) {
113223017Sdim  if (Overridden->hasRelatedResultType() &&
114223017Sdim      !NewMethod->hasRelatedResultType()) {
115223017Sdim    // This can only happen when the method follows a naming convention that
116223017Sdim    // implies a related result type, and the original (overridden) method has
117223017Sdim    // a suitable return type, but the new (overriding) method does not have
118223017Sdim    // a suitable return type.
119223017Sdim    QualType ResultType = NewMethod->getResultType();
120223017Sdim    SourceRange ResultTypeRange;
121223017Sdim    if (const TypeSourceInfo *ResultTypeInfo
122224145Sdim                                        = NewMethod->getResultTypeSourceInfo())
123223017Sdim      ResultTypeRange = ResultTypeInfo->getTypeLoc().getSourceRange();
124223017Sdim
125223017Sdim    // Figure out which class this method is part of, if any.
126223017Sdim    ObjCInterfaceDecl *CurrentClass
127223017Sdim      = dyn_cast<ObjCInterfaceDecl>(NewMethod->getDeclContext());
128223017Sdim    if (!CurrentClass) {
129223017Sdim      DeclContext *DC = NewMethod->getDeclContext();
130223017Sdim      if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(DC))
131223017Sdim        CurrentClass = Cat->getClassInterface();
132223017Sdim      else if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(DC))
133223017Sdim        CurrentClass = Impl->getClassInterface();
134223017Sdim      else if (ObjCCategoryImplDecl *CatImpl
135223017Sdim               = dyn_cast<ObjCCategoryImplDecl>(DC))
136223017Sdim        CurrentClass = CatImpl->getClassInterface();
137223017Sdim    }
138223017Sdim
139223017Sdim    if (CurrentClass) {
140223017Sdim      Diag(NewMethod->getLocation(),
141223017Sdim           diag::warn_related_result_type_compatibility_class)
142223017Sdim        << Context.getObjCInterfaceType(CurrentClass)
143223017Sdim        << ResultType
144223017Sdim        << ResultTypeRange;
145223017Sdim    } else {
146223017Sdim      Diag(NewMethod->getLocation(),
147223017Sdim           diag::warn_related_result_type_compatibility_protocol)
148223017Sdim        << ResultType
149223017Sdim        << ResultTypeRange;
150223017Sdim    }
151223017Sdim
152226633Sdim    if (ObjCMethodFamily Family = Overridden->getMethodFamily())
153226633Sdim      Diag(Overridden->getLocation(),
154249423Sdim           diag::note_related_result_type_family)
155249423Sdim        << /*overridden method*/ 0
156226633Sdim        << Family;
157226633Sdim    else
158226633Sdim      Diag(Overridden->getLocation(),
159226633Sdim           diag::note_related_result_type_overridden);
160223017Sdim  }
161234353Sdim  if (getLangOpts().ObjCAutoRefCount) {
162226633Sdim    if ((NewMethod->hasAttr<NSReturnsRetainedAttr>() !=
163226633Sdim         Overridden->hasAttr<NSReturnsRetainedAttr>())) {
164226633Sdim        Diag(NewMethod->getLocation(),
165226633Sdim             diag::err_nsreturns_retained_attribute_mismatch) << 1;
166226633Sdim        Diag(Overridden->getLocation(), diag::note_previous_decl)
167226633Sdim        << "method";
168223017Sdim    }
169226633Sdim    if ((NewMethod->hasAttr<NSReturnsNotRetainedAttr>() !=
170226633Sdim              Overridden->hasAttr<NSReturnsNotRetainedAttr>())) {
171226633Sdim        Diag(NewMethod->getLocation(),
172226633Sdim             diag::err_nsreturns_retained_attribute_mismatch) << 0;
173226633Sdim        Diag(Overridden->getLocation(), diag::note_previous_decl)
174226633Sdim        << "method";
175223017Sdim    }
176239462Sdim    ObjCMethodDecl::param_const_iterator oi = Overridden->param_begin(),
177239462Sdim                                         oe = Overridden->param_end();
178226633Sdim    for (ObjCMethodDecl::param_iterator
179226633Sdim           ni = NewMethod->param_begin(), ne = NewMethod->param_end();
180239462Sdim         ni != ne && oi != oe; ++ni, ++oi) {
181226633Sdim      const ParmVarDecl *oldDecl = (*oi);
182226633Sdim      ParmVarDecl *newDecl = (*ni);
183226633Sdim      if (newDecl->hasAttr<NSConsumedAttr>() !=
184226633Sdim          oldDecl->hasAttr<NSConsumedAttr>()) {
185226633Sdim        Diag(newDecl->getLocation(),
186226633Sdim             diag::err_nsconsumed_attribute_mismatch);
187226633Sdim        Diag(oldDecl->getLocation(), diag::note_previous_decl)
188226633Sdim          << "parameter";
189226633Sdim      }
190226633Sdim    }
191223017Sdim  }
192223017Sdim}
193223017Sdim
194224145Sdim/// \brief Check a method declaration for compatibility with the Objective-C
195224145Sdim/// ARC conventions.
196249423Sdimbool Sema::CheckARCMethodDecl(ObjCMethodDecl *method) {
197224145Sdim  ObjCMethodFamily family = method->getMethodFamily();
198224145Sdim  switch (family) {
199224145Sdim  case OMF_None:
200226633Sdim  case OMF_finalize:
201224145Sdim  case OMF_retain:
202224145Sdim  case OMF_release:
203224145Sdim  case OMF_autorelease:
204224145Sdim  case OMF_retainCount:
205224145Sdim  case OMF_self:
206226633Sdim  case OMF_performSelector:
207224145Sdim    return false;
208224145Sdim
209239462Sdim  case OMF_dealloc:
210249423Sdim    if (!Context.hasSameType(method->getResultType(), Context.VoidTy)) {
211239462Sdim      SourceRange ResultTypeRange;
212239462Sdim      if (const TypeSourceInfo *ResultTypeInfo
213239462Sdim          = method->getResultTypeSourceInfo())
214239462Sdim        ResultTypeRange = ResultTypeInfo->getTypeLoc().getSourceRange();
215239462Sdim      if (ResultTypeRange.isInvalid())
216249423Sdim        Diag(method->getLocation(), diag::error_dealloc_bad_result_type)
217239462Sdim          << method->getResultType()
218239462Sdim          << FixItHint::CreateInsertion(method->getSelectorLoc(0), "(void)");
219239462Sdim      else
220249423Sdim        Diag(method->getLocation(), diag::error_dealloc_bad_result_type)
221239462Sdim          << method->getResultType()
222239462Sdim          << FixItHint::CreateReplacement(ResultTypeRange, "void");
223239462Sdim      return true;
224239462Sdim    }
225239462Sdim    return false;
226239462Sdim
227224145Sdim  case OMF_init:
228224145Sdim    // If the method doesn't obey the init rules, don't bother annotating it.
229249423Sdim    if (checkInitMethod(method, QualType()))
230224145Sdim      return true;
231224145Sdim
232249423Sdim    method->addAttr(new (Context) NSConsumesSelfAttr(SourceLocation(),
233249423Sdim                                                     Context));
234224145Sdim
235224145Sdim    // Don't add a second copy of this attribute, but otherwise don't
236224145Sdim    // let it be suppressed.
237224145Sdim    if (method->hasAttr<NSReturnsRetainedAttr>())
238224145Sdim      return false;
239224145Sdim    break;
240224145Sdim
241224145Sdim  case OMF_alloc:
242224145Sdim  case OMF_copy:
243224145Sdim  case OMF_mutableCopy:
244224145Sdim  case OMF_new:
245224145Sdim    if (method->hasAttr<NSReturnsRetainedAttr>() ||
246224145Sdim        method->hasAttr<NSReturnsNotRetainedAttr>() ||
247224145Sdim        method->hasAttr<NSReturnsAutoreleasedAttr>())
248224145Sdim      return false;
249224145Sdim    break;
250224145Sdim  }
251224145Sdim
252249423Sdim  method->addAttr(new (Context) NSReturnsRetainedAttr(SourceLocation(),
253249423Sdim                                                      Context));
254224145Sdim  return false;
255224145Sdim}
256224145Sdim
257218893Sdimstatic void DiagnoseObjCImplementedDeprecations(Sema &S,
258218893Sdim                                                NamedDecl *ND,
259218893Sdim                                                SourceLocation ImplLoc,
260218893Sdim                                                int select) {
261221345Sdim  if (ND && ND->isDeprecated()) {
262218893Sdim    S.Diag(ImplLoc, diag::warn_deprecated_def) << select;
263218893Sdim    if (select == 0)
264234353Sdim      S.Diag(ND->getLocation(), diag::note_method_declared_at)
265234353Sdim        << ND->getDeclName();
266218893Sdim    else
267218893Sdim      S.Diag(ND->getLocation(), diag::note_previous_decl) << "class";
268218893Sdim  }
269218893Sdim}
270218893Sdim
271226633Sdim/// AddAnyMethodToGlobalPool - Add any method, instance or factory to global
272226633Sdim/// pool.
273226633Sdimvoid Sema::AddAnyMethodToGlobalPool(Decl *D) {
274226633Sdim  ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
275226633Sdim
276226633Sdim  // If we don't have a valid method decl, simply return.
277226633Sdim  if (!MDecl)
278226633Sdim    return;
279226633Sdim  if (MDecl->isInstanceMethod())
280226633Sdim    AddInstanceMethodToGlobalPool(MDecl, true);
281226633Sdim  else
282226633Sdim    AddFactoryMethodToGlobalPool(MDecl, true);
283226633Sdim}
284226633Sdim
285243830Sdim/// HasExplicitOwnershipAttr - returns true when pointer to ObjC pointer
286243830Sdim/// has explicit ownership attribute; false otherwise.
287243830Sdimstatic bool
288243830SdimHasExplicitOwnershipAttr(Sema &S, ParmVarDecl *Param) {
289243830Sdim  QualType T = Param->getType();
290243830Sdim
291243830Sdim  if (const PointerType *PT = T->getAs<PointerType>()) {
292243830Sdim    T = PT->getPointeeType();
293243830Sdim  } else if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
294243830Sdim    T = RT->getPointeeType();
295243830Sdim  } else {
296243830Sdim    return true;
297243830Sdim  }
298243830Sdim
299243830Sdim  // If we have a lifetime qualifier, but it's local, we must have
300243830Sdim  // inferred it. So, it is implicit.
301243830Sdim  return !T.getLocalQualifiers().hasObjCLifetime();
302243830Sdim}
303243830Sdim
304193326Sed/// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
305193326Sed/// and user declared, in the method definition's AST.
306212904Sdimvoid Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
307239462Sdim  assert((getCurMethodDecl() == 0) && "Methodparsing confused");
308212904Sdim  ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
309239462Sdim
310193326Sed  // If we don't have a valid method decl, simply return.
311193326Sed  if (!MDecl)
312193326Sed    return;
313193326Sed
314193326Sed  // Allow all of Sema to see that we are entering a method definition.
315193326Sed  PushDeclContext(FnBodyScope, MDecl);
316204643Srdivacky  PushFunctionScope();
317204643Srdivacky
318193326Sed  // Create Decl objects for each parameter, entrring them in the scope for
319193326Sed  // binding to their use.
320193326Sed
321193326Sed  // Insert the invisible arguments, self and _cmd!
322193326Sed  MDecl->createImplicitParams(Context, MDecl->getClassInterface());
323198092Srdivacky
324193326Sed  PushOnScopeChains(MDecl->getSelfDecl(), FnBodyScope);
325193326Sed  PushOnScopeChains(MDecl->getCmdDecl(), FnBodyScope);
326193326Sed
327263508Sdim  // The ObjC parser requires parameter names so there's no need to check.
328263508Sdim  CheckParmsForFunctionDef(MDecl->param_begin(), MDecl->param_end(),
329263508Sdim                           /*CheckParameterNames=*/false);
330263508Sdim
331193326Sed  // Introduce all of the other parameters into this scope.
332193326Sed  for (ObjCMethodDecl::param_iterator PI = MDecl->param_begin(),
333218893Sdim       E = MDecl->param_end(); PI != E; ++PI) {
334218893Sdim    ParmVarDecl *Param = (*PI);
335218893Sdim    if (!Param->isInvalidDecl() &&
336243830Sdim        getLangOpts().ObjCAutoRefCount &&
337243830Sdim        !HasExplicitOwnershipAttr(*this, Param))
338243830Sdim      Diag(Param->getLocation(), diag::warn_arc_strong_pointer_objc_pointer) <<
339243830Sdim            Param->getType();
340243830Sdim
341193326Sed    if ((*PI)->getIdentifier())
342193326Sed      PushOnScopeChains(*PI, FnBodyScope);
343218893Sdim  }
344224145Sdim
345224145Sdim  // In ARC, disallow definition of retain/release/autorelease/retainCount
346234353Sdim  if (getLangOpts().ObjCAutoRefCount) {
347224145Sdim    switch (MDecl->getMethodFamily()) {
348224145Sdim    case OMF_retain:
349224145Sdim    case OMF_retainCount:
350224145Sdim    case OMF_release:
351224145Sdim    case OMF_autorelease:
352224145Sdim      Diag(MDecl->getLocation(), diag::err_arc_illegal_method_def)
353263508Sdim        << 0 << MDecl->getSelector();
354224145Sdim      break;
355224145Sdim
356224145Sdim    case OMF_None:
357224145Sdim    case OMF_dealloc:
358226633Sdim    case OMF_finalize:
359224145Sdim    case OMF_alloc:
360224145Sdim    case OMF_init:
361224145Sdim    case OMF_mutableCopy:
362224145Sdim    case OMF_copy:
363224145Sdim    case OMF_new:
364224145Sdim    case OMF_self:
365224145Sdim    case OMF_performSelector:
366224145Sdim      break;
367224145Sdim    }
368224145Sdim  }
369224145Sdim
370226633Sdim  // Warn on deprecated methods under -Wdeprecated-implementations,
371226633Sdim  // and prepare for warning on missing super calls.
372226633Sdim  if (ObjCInterfaceDecl *IC = MDecl->getClassInterface()) {
373243830Sdim    ObjCMethodDecl *IMD =
374243830Sdim      IC->lookupMethod(MDecl->getSelector(), MDecl->isInstanceMethod());
375243830Sdim
376249423Sdim    if (IMD) {
377249423Sdim      ObjCImplDecl *ImplDeclOfMethodDef =
378249423Sdim        dyn_cast<ObjCImplDecl>(MDecl->getDeclContext());
379249423Sdim      ObjCContainerDecl *ContDeclOfMethodDecl =
380249423Sdim        dyn_cast<ObjCContainerDecl>(IMD->getDeclContext());
381249423Sdim      ObjCImplDecl *ImplDeclOfMethodDecl = 0;
382249423Sdim      if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ContDeclOfMethodDecl))
383249423Sdim        ImplDeclOfMethodDecl = OID->getImplementation();
384249423Sdim      else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(ContDeclOfMethodDecl))
385249423Sdim        ImplDeclOfMethodDecl = CD->getImplementation();
386249423Sdim      // No need to issue deprecated warning if deprecated mehod in class/category
387249423Sdim      // is being implemented in its own implementation (no overriding is involved).
388249423Sdim      if (!ImplDeclOfMethodDecl || ImplDeclOfMethodDecl != ImplDeclOfMethodDef)
389249423Sdim        DiagnoseObjCImplementedDeprecations(*this,
390218893Sdim                                          dyn_cast<NamedDecl>(IMD),
391218893Sdim                                          MDecl->getLocation(), 0);
392249423Sdim    }
393226633Sdim
394226633Sdim    // If this is "dealloc" or "finalize", set some bit here.
395226633Sdim    // Then in ActOnSuperMessage() (SemaExprObjC), set it back to false.
396226633Sdim    // Finally, in ActOnFinishFunctionBody() (SemaDecl), warn if flag is set.
397226633Sdim    // Only do this if the current class actually has a superclass.
398249423Sdim    if (const ObjCInterfaceDecl *SuperClass = IC->getSuperClass()) {
399243830Sdim      ObjCMethodFamily Family = MDecl->getMethodFamily();
400243830Sdim      if (Family == OMF_dealloc) {
401243830Sdim        if (!(getLangOpts().ObjCAutoRefCount ||
402243830Sdim              getLangOpts().getGC() == LangOptions::GCOnly))
403243830Sdim          getCurFunction()->ObjCShouldCallSuper = true;
404243830Sdim
405243830Sdim      } else if (Family == OMF_finalize) {
406243830Sdim        if (Context.getLangOpts().getGC() != LangOptions::NonGC)
407243830Sdim          getCurFunction()->ObjCShouldCallSuper = true;
408243830Sdim
409243830Sdim      } else {
410243830Sdim        const ObjCMethodDecl *SuperMethod =
411249423Sdim          SuperClass->lookupMethod(MDecl->getSelector(),
412249423Sdim                                   MDecl->isInstanceMethod());
413243830Sdim        getCurFunction()->ObjCShouldCallSuper =
414243830Sdim          (SuperMethod && SuperMethod->hasAttr<ObjCRequiresSuperAttr>());
415243830Sdim      }
416226633Sdim    }
417226633Sdim  }
418193326Sed}
419193326Sed
420234353Sdimnamespace {
421234353Sdim
422234353Sdim// Callback to only accept typo corrections that are Objective-C classes.
423234353Sdim// If an ObjCInterfaceDecl* is given to the constructor, then the validation
424234353Sdim// function will reject corrections to that class.
425234353Sdimclass ObjCInterfaceValidatorCCC : public CorrectionCandidateCallback {
426234353Sdim public:
427234353Sdim  ObjCInterfaceValidatorCCC() : CurrentIDecl(0) {}
428234353Sdim  explicit ObjCInterfaceValidatorCCC(ObjCInterfaceDecl *IDecl)
429234353Sdim      : CurrentIDecl(IDecl) {}
430234353Sdim
431234353Sdim  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
432234353Sdim    ObjCInterfaceDecl *ID = candidate.getCorrectionDeclAs<ObjCInterfaceDecl>();
433234353Sdim    return ID && !declaresSameEntity(ID, CurrentIDecl);
434234353Sdim  }
435234353Sdim
436234353Sdim private:
437234353Sdim  ObjCInterfaceDecl *CurrentIDecl;
438234353Sdim};
439234353Sdim
440234353Sdim}
441234353Sdim
442212904SdimDecl *Sema::
443193326SedActOnStartClassInterface(SourceLocation AtInterfaceLoc,
444193326Sed                         IdentifierInfo *ClassName, SourceLocation ClassLoc,
445193326Sed                         IdentifierInfo *SuperName, SourceLocation SuperLoc,
446212904Sdim                         Decl * const *ProtoRefs, unsigned NumProtoRefs,
447202879Srdivacky                         const SourceLocation *ProtoLocs,
448193326Sed                         SourceLocation EndProtoLoc, AttributeList *AttrList) {
449193326Sed  assert(ClassName && "Missing class identifier");
450198092Srdivacky
451193326Sed  // Check for another declaration kind with the same name.
452207619Srdivacky  NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, ClassLoc,
453207619Srdivacky                                         LookupOrdinaryName, ForRedeclaration);
454193326Sed
455193326Sed  if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
456193326Sed    Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
457193326Sed    Diag(PrevDecl->getLocation(), diag::note_previous_definition);
458193326Sed  }
459198092Srdivacky
460234353Sdim  // Create a declaration to describe this @interface.
461234353Sdim  ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
462263508Sdim
463263508Sdim  if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) {
464263508Sdim    // A previous decl with a different name is because of
465263508Sdim    // @compatibility_alias, for example:
466263508Sdim    // \code
467263508Sdim    //   @class NewImage;
468263508Sdim    //   @compatibility_alias OldImage NewImage;
469263508Sdim    // \endcode
470263508Sdim    // A lookup for 'OldImage' will return the 'NewImage' decl.
471263508Sdim    //
472263508Sdim    // In such a case use the real declaration name, instead of the alias one,
473263508Sdim    // otherwise we will break IdentifierResolver and redecls-chain invariants.
474263508Sdim    // FIXME: If necessary, add a bit to indicate that this ObjCInterfaceDecl
475263508Sdim    // has been aliased.
476263508Sdim    ClassName = PrevIDecl->getIdentifier();
477263508Sdim  }
478263508Sdim
479234353Sdim  ObjCInterfaceDecl *IDecl
480234353Sdim    = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName,
481234353Sdim                                PrevIDecl, ClassLoc);
482234353Sdim
483234353Sdim  if (PrevIDecl) {
484234353Sdim    // Class already seen. Was it a definition?
485234353Sdim    if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) {
486234353Sdim      Diag(AtInterfaceLoc, diag::err_duplicate_class_def)
487234353Sdim        << PrevIDecl->getDeclName();
488234353Sdim      Diag(Def->getLocation(), diag::note_previous_definition);
489193326Sed      IDecl->setInvalidDecl();
490193326Sed    }
491193326Sed  }
492234353Sdim
493234353Sdim  if (AttrList)
494234353Sdim    ProcessDeclAttributeList(TUScope, IDecl, AttrList);
495234353Sdim  PushOnScopeChains(IDecl, TUScope);
496198092Srdivacky
497234353Sdim  // Start the definition of this class. If we're in a redefinition case, there
498234353Sdim  // may already be a definition, so we'll end up adding to it.
499234353Sdim  if (!IDecl->hasDefinition())
500234353Sdim    IDecl->startDefinition();
501234353Sdim
502193326Sed  if (SuperName) {
503193326Sed    // Check if a different kind of symbol declared in this scope.
504207619Srdivacky    PrevDecl = LookupSingleName(TUScope, SuperName, SuperLoc,
505207619Srdivacky                                LookupOrdinaryName);
506202379Srdivacky
507202379Srdivacky    if (!PrevDecl) {
508234353Sdim      // Try to correct for a typo in the superclass name without correcting
509234353Sdim      // to the class we're defining.
510234353Sdim      ObjCInterfaceValidatorCCC Validator(IDecl);
511234353Sdim      if (TypoCorrection Corrected = CorrectTypo(
512224145Sdim          DeclarationNameInfo(SuperName, SuperLoc), LookupOrdinaryName, TUScope,
513234353Sdim          NULL, Validator)) {
514263508Sdim        diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest)
515263508Sdim                                    << SuperName << ClassName);
516234353Sdim        PrevDecl = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>();
517202379Srdivacky      }
518202379Srdivacky    }
519202379Srdivacky
520234353Sdim    if (declaresSameEntity(PrevDecl, IDecl)) {
521198092Srdivacky      Diag(SuperLoc, diag::err_recursive_superclass)
522198092Srdivacky        << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
523234353Sdim      IDecl->setEndOfDefinitionLoc(ClassLoc);
524198092Srdivacky    } else {
525198092Srdivacky      ObjCInterfaceDecl *SuperClassDecl =
526198092Srdivacky                                dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
527193326Sed
528198092Srdivacky      // Diagnose classes that inherit from deprecated classes.
529198092Srdivacky      if (SuperClassDecl)
530198092Srdivacky        (void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc);
531193326Sed
532198092Srdivacky      if (PrevDecl && SuperClassDecl == 0) {
533198092Srdivacky        // The previous declaration was not a class decl. Check if we have a
534198092Srdivacky        // typedef. If we do, get the underlying class type.
535221345Sdim        if (const TypedefNameDecl *TDecl =
536221345Sdim              dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) {
537198092Srdivacky          QualType T = TDecl->getUnderlyingType();
538208600Srdivacky          if (T->isObjCObjectType()) {
539249423Sdim            if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface()) {
540198092Srdivacky              SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
541249423Sdim              // This handles the following case:
542249423Sdim              // @interface NewI @end
543249423Sdim              // typedef NewI DeprI __attribute__((deprecated("blah")))
544249423Sdim              // @interface SI : DeprI /* warn here */ @end
545249423Sdim              (void)DiagnoseUseOfDecl(const_cast<TypedefNameDecl*>(TDecl), SuperLoc);
546249423Sdim            }
547198092Srdivacky          }
548193326Sed        }
549198092Srdivacky
550198092Srdivacky        // This handles the following case:
551198092Srdivacky        //
552198092Srdivacky        // typedef int SuperClass;
553198092Srdivacky        // @interface MyClass : SuperClass {} @end
554198092Srdivacky        //
555198092Srdivacky        if (!SuperClassDecl) {
556198092Srdivacky          Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
557198092Srdivacky          Diag(PrevDecl->getLocation(), diag::note_previous_definition);
558198092Srdivacky        }
559193326Sed      }
560198092Srdivacky
561221345Sdim      if (!dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) {
562198092Srdivacky        if (!SuperClassDecl)
563198092Srdivacky          Diag(SuperLoc, diag::err_undef_superclass)
564198092Srdivacky            << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
565234353Sdim        else if (RequireCompleteType(SuperLoc,
566239462Sdim                                  Context.getObjCInterfaceType(SuperClassDecl),
567239462Sdim                                     diag::err_forward_superclass,
568239462Sdim                                     SuperClassDecl->getDeclName(),
569239462Sdim                                     ClassName,
570239462Sdim                                     SourceRange(AtInterfaceLoc, ClassLoc))) {
571224145Sdim          SuperClassDecl = 0;
572224145Sdim        }
573193326Sed      }
574198092Srdivacky      IDecl->setSuperClass(SuperClassDecl);
575198092Srdivacky      IDecl->setSuperClassLoc(SuperLoc);
576234353Sdim      IDecl->setEndOfDefinitionLoc(SuperLoc);
577193326Sed    }
578193326Sed  } else { // we have a root class.
579234353Sdim    IDecl->setEndOfDefinitionLoc(ClassLoc);
580193326Sed  }
581198092Srdivacky
582212904Sdim  // Check then save referenced protocols.
583193326Sed  if (NumProtoRefs) {
584243830Sdim    IDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs,
585202879Srdivacky                           ProtoLocs, Context);
586234353Sdim    IDecl->setEndOfDefinitionLoc(EndProtoLoc);
587193326Sed  }
588198092Srdivacky
589193326Sed  CheckObjCDeclScope(IDecl);
590226633Sdim  return ActOnObjCContainerStartDefinition(IDecl);
591193326Sed}
592193326Sed
593263508Sdim/// ActOnTypedefedProtocols - this action finds protocol list as part of the
594263508Sdim/// typedef'ed use for a qualified super class and adds them to the list
595263508Sdim/// of the protocols.
596263508Sdimvoid Sema::ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs,
597263508Sdim                                   IdentifierInfo *SuperName,
598263508Sdim                                   SourceLocation SuperLoc) {
599263508Sdim  if (!SuperName)
600263508Sdim    return;
601263508Sdim  NamedDecl* IDecl = LookupSingleName(TUScope, SuperName, SuperLoc,
602263508Sdim                                      LookupOrdinaryName);
603263508Sdim  if (!IDecl)
604263508Sdim    return;
605263508Sdim
606263508Sdim  if (const TypedefNameDecl *TDecl = dyn_cast_or_null<TypedefNameDecl>(IDecl)) {
607263508Sdim    QualType T = TDecl->getUnderlyingType();
608263508Sdim    if (T->isObjCObjectType())
609263508Sdim      if (const ObjCObjectType *OPT = T->getAs<ObjCObjectType>())
610263508Sdim        for (ObjCObjectType::qual_iterator I = OPT->qual_begin(),
611263508Sdim             E = OPT->qual_end(); I != E; ++I)
612263508Sdim          ProtocolRefs.push_back(*I);
613263508Sdim  }
614263508Sdim}
615263508Sdim
616239462Sdim/// ActOnCompatibilityAlias - this action is called after complete parsing of
617239462Sdim/// a \@compatibility_alias declaration. It sets up the alias relationships.
618239462SdimDecl *Sema::ActOnCompatibilityAlias(SourceLocation AtLoc,
619239462Sdim                                    IdentifierInfo *AliasName,
620239462Sdim                                    SourceLocation AliasLocation,
621239462Sdim                                    IdentifierInfo *ClassName,
622239462Sdim                                    SourceLocation ClassLocation) {
623193326Sed  // Look for previous declaration of alias name
624207619Srdivacky  NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, AliasLocation,
625207619Srdivacky                                      LookupOrdinaryName, ForRedeclaration);
626193326Sed  if (ADecl) {
627263508Sdim    Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName;
628193326Sed    Diag(ADecl->getLocation(), diag::note_previous_declaration);
629212904Sdim    return 0;
630193326Sed  }
631193326Sed  // Check for class declaration
632207619Srdivacky  NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
633207619Srdivacky                                       LookupOrdinaryName, ForRedeclaration);
634221345Sdim  if (const TypedefNameDecl *TDecl =
635221345Sdim        dyn_cast_or_null<TypedefNameDecl>(CDeclU)) {
636193326Sed    QualType T = TDecl->getUnderlyingType();
637208600Srdivacky    if (T->isObjCObjectType()) {
638208600Srdivacky      if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface()) {
639193326Sed        ClassName = IDecl->getIdentifier();
640207619Srdivacky        CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
641207619Srdivacky                                  LookupOrdinaryName, ForRedeclaration);
642193326Sed      }
643193326Sed    }
644193326Sed  }
645193326Sed  ObjCInterfaceDecl *CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDeclU);
646193326Sed  if (CDecl == 0) {
647193326Sed    Diag(ClassLocation, diag::warn_undef_interface) << ClassName;
648193326Sed    if (CDeclU)
649193326Sed      Diag(CDeclU->getLocation(), diag::note_previous_declaration);
650212904Sdim    return 0;
651193326Sed  }
652198092Srdivacky
653193326Sed  // Everything checked out, instantiate a new alias declaration AST.
654198092Srdivacky  ObjCCompatibleAliasDecl *AliasDecl =
655193326Sed    ObjCCompatibleAliasDecl::Create(Context, CurContext, AtLoc, AliasName, CDecl);
656198092Srdivacky
657193326Sed  if (!CheckObjCDeclScope(AliasDecl))
658193326Sed    PushOnScopeChains(AliasDecl, TUScope);
659193326Sed
660212904Sdim  return AliasDecl;
661193326Sed}
662193326Sed
663223017Sdimbool Sema::CheckForwardProtocolDeclarationForCircularDependency(
664193326Sed  IdentifierInfo *PName,
665193326Sed  SourceLocation &Ploc, SourceLocation PrevLoc,
666198092Srdivacky  const ObjCList<ObjCProtocolDecl> &PList) {
667223017Sdim
668223017Sdim  bool res = false;
669193326Sed  for (ObjCList<ObjCProtocolDecl>::iterator I = PList.begin(),
670193326Sed       E = PList.end(); I != E; ++I) {
671207619Srdivacky    if (ObjCProtocolDecl *PDecl = LookupProtocol((*I)->getIdentifier(),
672207619Srdivacky                                                 Ploc)) {
673193326Sed      if (PDecl->getIdentifier() == PName) {
674193326Sed        Diag(Ploc, diag::err_protocol_has_circular_dependency);
675193326Sed        Diag(PrevLoc, diag::note_previous_definition);
676223017Sdim        res = true;
677193326Sed      }
678234353Sdim
679234353Sdim      if (!PDecl->hasDefinition())
680234353Sdim        continue;
681234353Sdim
682223017Sdim      if (CheckForwardProtocolDeclarationForCircularDependency(PName, Ploc,
683223017Sdim            PDecl->getLocation(), PDecl->getReferencedProtocols()))
684223017Sdim        res = true;
685193326Sed    }
686193326Sed  }
687223017Sdim  return res;
688193326Sed}
689193326Sed
690212904SdimDecl *
691193326SedSema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
692193326Sed                                  IdentifierInfo *ProtocolName,
693193326Sed                                  SourceLocation ProtocolLoc,
694212904Sdim                                  Decl * const *ProtoRefs,
695193326Sed                                  unsigned NumProtoRefs,
696202879Srdivacky                                  const SourceLocation *ProtoLocs,
697193326Sed                                  SourceLocation EndProtoLoc,
698193326Sed                                  AttributeList *AttrList) {
699223017Sdim  bool err = false;
700193326Sed  // FIXME: Deal with AttrList.
701193326Sed  assert(ProtocolName && "Missing protocol identifier");
702234353Sdim  ObjCProtocolDecl *PrevDecl = LookupProtocol(ProtocolName, ProtocolLoc,
703234353Sdim                                              ForRedeclaration);
704234353Sdim  ObjCProtocolDecl *PDecl = 0;
705234353Sdim  if (ObjCProtocolDecl *Def = PrevDecl? PrevDecl->getDefinition() : 0) {
706234353Sdim    // If we already have a definition, complain.
707234353Sdim    Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName;
708234353Sdim    Diag(Def->getLocation(), diag::note_previous_definition);
709234353Sdim
710234353Sdim    // Create a new protocol that is completely distinct from previous
711234353Sdim    // declarations, and do not make this protocol available for name lookup.
712234353Sdim    // That way, we'll end up completely ignoring the duplicate.
713234353Sdim    // FIXME: Can we turn this into an error?
714234353Sdim    PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName,
715234353Sdim                                     ProtocolLoc, AtProtoInterfaceLoc,
716234353Sdim                                     /*PrevDecl=*/0);
717234353Sdim    PDecl->startDefinition();
718234353Sdim  } else {
719234353Sdim    if (PrevDecl) {
720234353Sdim      // Check for circular dependencies among protocol declarations. This can
721234353Sdim      // only happen if this protocol was forward-declared.
722234353Sdim      ObjCList<ObjCProtocolDecl> PList;
723234353Sdim      PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context);
724234353Sdim      err = CheckForwardProtocolDeclarationForCircularDependency(
725234353Sdim              ProtocolName, ProtocolLoc, PrevDecl->getLocation(), PList);
726193326Sed    }
727198092Srdivacky
728234353Sdim    // Create the new declaration.
729226633Sdim    PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName,
730234353Sdim                                     ProtocolLoc, AtProtoInterfaceLoc,
731234353Sdim                                     /*PrevDecl=*/PrevDecl);
732234353Sdim
733193326Sed    PushOnScopeChains(PDecl, TUScope);
734234353Sdim    PDecl->startDefinition();
735193326Sed  }
736234353Sdim
737193326Sed  if (AttrList)
738194613Sed    ProcessDeclAttributeList(TUScope, PDecl, AttrList);
739234353Sdim
740234353Sdim  // Merge attributes from previous declarations.
741234353Sdim  if (PrevDecl)
742234353Sdim    mergeDeclAttributes(PDecl, PrevDecl);
743234353Sdim
744223017Sdim  if (!err && NumProtoRefs ) {
745193326Sed    /// Check then save referenced protocols.
746243830Sdim    PDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs,
747202879Srdivacky                           ProtoLocs, Context);
748193326Sed  }
749198092Srdivacky
750198092Srdivacky  CheckObjCDeclScope(PDecl);
751226633Sdim  return ActOnObjCContainerStartDefinition(PDecl);
752193326Sed}
753193326Sed
754193326Sed/// FindProtocolDeclaration - This routine looks up protocols and
755193326Sed/// issues an error if they are not declared. It returns list of
756193326Sed/// protocol declarations in its 'Protocols' argument.
757193326Sedvoid
758193326SedSema::FindProtocolDeclaration(bool WarnOnDeclarations,
759193326Sed                              const IdentifierLocPair *ProtocolId,
760193326Sed                              unsigned NumProtocols,
761226633Sdim                              SmallVectorImpl<Decl *> &Protocols) {
762193326Sed  for (unsigned i = 0; i != NumProtocols; ++i) {
763207619Srdivacky    ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolId[i].first,
764207619Srdivacky                                             ProtocolId[i].second);
765193326Sed    if (!PDecl) {
766234353Sdim      DeclFilterCCC<ObjCProtocolDecl> Validator;
767224145Sdim      TypoCorrection Corrected = CorrectTypo(
768224145Sdim          DeclarationNameInfo(ProtocolId[i].first, ProtocolId[i].second),
769234353Sdim          LookupObjCProtocolName, TUScope, NULL, Validator);
770263508Sdim      if ((PDecl = Corrected.getCorrectionDeclAs<ObjCProtocolDecl>()))
771263508Sdim        diagnoseTypo(Corrected, PDiag(diag::err_undeclared_protocol_suggest)
772263508Sdim                                    << ProtocolId[i].first);
773202379Srdivacky    }
774202379Srdivacky
775202379Srdivacky    if (!PDecl) {
776193326Sed      Diag(ProtocolId[i].second, diag::err_undeclared_protocol)
777193326Sed        << ProtocolId[i].first;
778193326Sed      continue;
779193326Sed    }
780251662Sdim    // If this is a forward protocol declaration, get its definition.
781251662Sdim    if (!PDecl->isThisDeclarationADefinition() && PDecl->getDefinition())
782251662Sdim      PDecl = PDecl->getDefinition();
783251662Sdim
784193326Sed    (void)DiagnoseUseOfDecl(PDecl, ProtocolId[i].second);
785193326Sed
786193326Sed    // If this is a forward declaration and we are supposed to warn in this
787193326Sed    // case, do it.
788249423Sdim    // FIXME: Recover nicely in the hidden case.
789249423Sdim    if (WarnOnDeclarations &&
790249423Sdim        (!PDecl->hasDefinition() || PDecl->getDefinition()->isHidden()))
791193326Sed      Diag(ProtocolId[i].second, diag::warn_undef_protocolref)
792193326Sed        << ProtocolId[i].first;
793212904Sdim    Protocols.push_back(PDecl);
794193326Sed  }
795193326Sed}
796193326Sed
797193326Sed/// DiagnoseClassExtensionDupMethods - Check for duplicate declaration of
798193326Sed/// a class method in its extension.
799193326Sed///
800198092Srdivackyvoid Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
801193326Sed                                            ObjCInterfaceDecl *ID) {
802193326Sed  if (!ID)
803193326Sed    return;  // Possibly due to previous error
804193326Sed
805193326Sed  llvm::DenseMap<Selector, const ObjCMethodDecl*> MethodMap;
806195341Sed  for (ObjCInterfaceDecl::method_iterator i = ID->meth_begin(),
807195341Sed       e =  ID->meth_end(); i != e; ++i) {
808193326Sed    ObjCMethodDecl *MD = *i;
809193326Sed    MethodMap[MD->getSelector()] = MD;
810193326Sed  }
811193326Sed
812193326Sed  if (MethodMap.empty())
813193326Sed    return;
814195341Sed  for (ObjCCategoryDecl::method_iterator i = CAT->meth_begin(),
815195341Sed       e =  CAT->meth_end(); i != e; ++i) {
816193326Sed    ObjCMethodDecl *Method = *i;
817193326Sed    const ObjCMethodDecl *&PrevMethod = MethodMap[Method->getSelector()];
818193326Sed    if (PrevMethod && !MatchTwoMethodDeclarations(Method, PrevMethod)) {
819193326Sed      Diag(Method->getLocation(), diag::err_duplicate_method_decl)
820193326Sed            << Method->getDeclName();
821193326Sed      Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
822193326Sed    }
823193326Sed  }
824193326Sed}
825193326Sed
826239462Sdim/// ActOnForwardProtocolDeclaration - Handle \@protocol foo;
827234353SdimSema::DeclGroupPtrTy
828193326SedSema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
829193326Sed                                      const IdentifierLocPair *IdentList,
830193326Sed                                      unsigned NumElts,
831193326Sed                                      AttributeList *attrList) {
832234353Sdim  SmallVector<Decl *, 8> DeclsInGroup;
833193326Sed  for (unsigned i = 0; i != NumElts; ++i) {
834193326Sed    IdentifierInfo *Ident = IdentList[i].first;
835234353Sdim    ObjCProtocolDecl *PrevDecl = LookupProtocol(Ident, IdentList[i].second,
836234353Sdim                                                ForRedeclaration);
837234353Sdim    ObjCProtocolDecl *PDecl
838234353Sdim      = ObjCProtocolDecl::Create(Context, CurContext, Ident,
839234353Sdim                                 IdentList[i].second, AtProtocolLoc,
840234353Sdim                                 PrevDecl);
841234353Sdim
842234353Sdim    PushOnScopeChains(PDecl, TUScope);
843234353Sdim    CheckObjCDeclScope(PDecl);
844234353Sdim
845234353Sdim    if (attrList)
846194613Sed      ProcessDeclAttributeList(TUScope, PDecl, attrList);
847234353Sdim
848234353Sdim    if (PrevDecl)
849234353Sdim      mergeDeclAttributes(PDecl, PrevDecl);
850234353Sdim
851234353Sdim    DeclsInGroup.push_back(PDecl);
852193326Sed  }
853198092Srdivacky
854263508Sdim  return BuildDeclaratorGroup(DeclsInGroup, false);
855193326Sed}
856193326Sed
857212904SdimDecl *Sema::
858193326SedActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
859193326Sed                            IdentifierInfo *ClassName, SourceLocation ClassLoc,
860193326Sed                            IdentifierInfo *CategoryName,
861193326Sed                            SourceLocation CategoryLoc,
862212904Sdim                            Decl * const *ProtoRefs,
863193326Sed                            unsigned NumProtoRefs,
864202879Srdivacky                            const SourceLocation *ProtoLocs,
865193326Sed                            SourceLocation EndProtoLoc) {
866210299Sed  ObjCCategoryDecl *CDecl;
867207619Srdivacky  ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true);
868204643Srdivacky
869204643Srdivacky  /// Check that class of this category is already completely declared.
870234353Sdim
871234353Sdim  if (!IDecl
872234353Sdim      || RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
873239462Sdim                             diag::err_category_forward_interface,
874239462Sdim                             CategoryName == 0)) {
875204643Srdivacky    // Create an invalid ObjCCategoryDecl to serve as context for
876204643Srdivacky    // the enclosing method declarations.  We mark the decl invalid
877204643Srdivacky    // to make it clear that this isn't a valid AST.
878204643Srdivacky    CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc,
879226633Sdim                                     ClassLoc, CategoryLoc, CategoryName,IDecl);
880204643Srdivacky    CDecl->setInvalidDecl();
881234353Sdim    CurContext->addDecl(CDecl);
882234353Sdim
883234353Sdim    if (!IDecl)
884234353Sdim      Diag(ClassLoc, diag::err_undef_interface) << ClassName;
885226633Sdim    return ActOnObjCContainerStartDefinition(CDecl);
886204643Srdivacky  }
887204643Srdivacky
888210299Sed  if (!CategoryName && IDecl->getImplementation()) {
889210299Sed    Diag(ClassLoc, diag::err_class_extension_after_impl) << ClassName;
890210299Sed    Diag(IDecl->getImplementation()->getLocation(),
891210299Sed          diag::note_implementation_declared);
892193326Sed  }
893204643Srdivacky
894203955Srdivacky  if (CategoryName) {
895203955Srdivacky    /// Check for duplicate interface declaration for this category
896249423Sdim    if (ObjCCategoryDecl *Previous
897249423Sdim          = IDecl->FindCategoryDeclaration(CategoryName)) {
898249423Sdim      // Class extensions can be declared multiple times, categories cannot.
899249423Sdim      Diag(CategoryLoc, diag::warn_dup_category_def)
900249423Sdim        << ClassName << CategoryName;
901249423Sdim      Diag(Previous->getLocation(), diag::note_previous_definition);
902193326Sed    }
903193326Sed  }
904193326Sed
905226633Sdim  CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc,
906226633Sdim                                   ClassLoc, CategoryLoc, CategoryName, IDecl);
907226633Sdim  // FIXME: PushOnScopeChains?
908226633Sdim  CurContext->addDecl(CDecl);
909226633Sdim
910193326Sed  if (NumProtoRefs) {
911243830Sdim    CDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs,
912202879Srdivacky                           ProtoLocs, Context);
913198092Srdivacky    // Protocols in the class extension belong to the class.
914203955Srdivacky    if (CDecl->IsClassExtension())
915243830Sdim     IDecl->mergeClassExtensionProtocolList((ObjCProtocolDecl*const*)ProtoRefs,
916212904Sdim                                            NumProtoRefs, Context);
917193326Sed  }
918198092Srdivacky
919193326Sed  CheckObjCDeclScope(CDecl);
920226633Sdim  return ActOnObjCContainerStartDefinition(CDecl);
921193326Sed}
922193326Sed
923193326Sed/// ActOnStartCategoryImplementation - Perform semantic checks on the
924193326Sed/// category implementation declaration and build an ObjCCategoryImplDecl
925193326Sed/// object.
926212904SdimDecl *Sema::ActOnStartCategoryImplementation(
927193326Sed                      SourceLocation AtCatImplLoc,
928193326Sed                      IdentifierInfo *ClassName, SourceLocation ClassLoc,
929193326Sed                      IdentifierInfo *CatName, SourceLocation CatLoc) {
930207619Srdivacky  ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true);
931198092Srdivacky  ObjCCategoryDecl *CatIDecl = 0;
932234353Sdim  if (IDecl && IDecl->hasDefinition()) {
933198092Srdivacky    CatIDecl = IDecl->FindCategoryDeclaration(CatName);
934198092Srdivacky    if (!CatIDecl) {
935198092Srdivacky      // Category @implementation with no corresponding @interface.
936198092Srdivacky      // Create and install one.
937234353Sdim      CatIDecl = ObjCCategoryDecl::Create(Context, CurContext, AtCatImplLoc,
938234353Sdim                                          ClassLoc, CatLoc,
939226633Sdim                                          CatName, IDecl);
940234353Sdim      CatIDecl->setImplicit();
941198092Srdivacky    }
942198092Srdivacky  }
943198092Srdivacky
944198092Srdivacky  ObjCCategoryImplDecl *CDecl =
945226633Sdim    ObjCCategoryImplDecl::Create(Context, CurContext, CatName, IDecl,
946234353Sdim                                 ClassLoc, AtCatImplLoc, CatLoc);
947193326Sed  /// Check that class of this category is already completely declared.
948234353Sdim  if (!IDecl) {
949193326Sed    Diag(ClassLoc, diag::err_undef_interface) << ClassName;
950226633Sdim    CDecl->setInvalidDecl();
951234353Sdim  } else if (RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
952234353Sdim                                 diag::err_undef_interface)) {
953234353Sdim    CDecl->setInvalidDecl();
954226633Sdim  }
955193326Sed
956193326Sed  // FIXME: PushOnScopeChains?
957195341Sed  CurContext->addDecl(CDecl);
958193326Sed
959226633Sdim  // If the interface is deprecated/unavailable, warn/error about it.
960226633Sdim  if (IDecl)
961226633Sdim    DiagnoseUseOfDecl(IDecl, ClassLoc);
962226633Sdim
963198092Srdivacky  /// Check that CatName, category name, is not used in another implementation.
964198092Srdivacky  if (CatIDecl) {
965198092Srdivacky    if (CatIDecl->getImplementation()) {
966198092Srdivacky      Diag(ClassLoc, diag::err_dup_implementation_category) << ClassName
967198092Srdivacky        << CatName;
968198092Srdivacky      Diag(CatIDecl->getImplementation()->getLocation(),
969198092Srdivacky           diag::note_previous_definition);
970263508Sdim      CDecl->setInvalidDecl();
971218893Sdim    } else {
972198092Srdivacky      CatIDecl->setImplementation(CDecl);
973218893Sdim      // Warn on implementating category of deprecated class under
974218893Sdim      // -Wdeprecated-implementations flag.
975218893Sdim      DiagnoseObjCImplementedDeprecations(*this,
976218893Sdim                                          dyn_cast<NamedDecl>(IDecl),
977218893Sdim                                          CDecl->getLocation(), 2);
978218893Sdim    }
979198092Srdivacky  }
980198092Srdivacky
981193326Sed  CheckObjCDeclScope(CDecl);
982226633Sdim  return ActOnObjCContainerStartDefinition(CDecl);
983193326Sed}
984193326Sed
985212904SdimDecl *Sema::ActOnStartClassImplementation(
986193326Sed                      SourceLocation AtClassImplLoc,
987193326Sed                      IdentifierInfo *ClassName, SourceLocation ClassLoc,
988198092Srdivacky                      IdentifierInfo *SuperClassname,
989193326Sed                      SourceLocation SuperClassLoc) {
990263508Sdim  ObjCInterfaceDecl *IDecl = 0;
991193326Sed  // Check for another declaration kind with the same name.
992198092Srdivacky  NamedDecl *PrevDecl
993207619Srdivacky    = LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName,
994207619Srdivacky                       ForRedeclaration);
995193326Sed  if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
996193326Sed    Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
997193326Sed    Diag(PrevDecl->getLocation(), diag::note_previous_definition);
998202379Srdivacky  } else if ((IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))) {
999234353Sdim    RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
1000234353Sdim                        diag::warn_undef_interface);
1001202379Srdivacky  } else {
1002263508Sdim    // We did not find anything with the name ClassName; try to correct for
1003202379Srdivacky    // typos in the class name.
1004234353Sdim    ObjCInterfaceValidatorCCC Validator;
1005263508Sdim    TypoCorrection Corrected =
1006263508Sdim            CorrectTypo(DeclarationNameInfo(ClassName, ClassLoc),
1007263508Sdim                        LookupOrdinaryName, TUScope, NULL, Validator);
1008263508Sdim    if (Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) {
1009263508Sdim      // Suggest the (potentially) correct interface name. Don't provide a
1010263508Sdim      // code-modification hint or use the typo name for recovery, because
1011263508Sdim      // this is just a warning. The program may actually be correct.
1012263508Sdim      diagnoseTypo(Corrected,
1013263508Sdim                   PDiag(diag::warn_undef_interface_suggest) << ClassName,
1014263508Sdim                   /*ErrorRecovery*/false);
1015202379Srdivacky    } else {
1016202379Srdivacky      Diag(ClassLoc, diag::warn_undef_interface) << ClassName;
1017202379Srdivacky    }
1018193326Sed  }
1019198092Srdivacky
1020193326Sed  // Check that super class name is valid class name
1021193326Sed  ObjCInterfaceDecl* SDecl = 0;
1022193326Sed  if (SuperClassname) {
1023193326Sed    // Check if a different kind of symbol declared in this scope.
1024207619Srdivacky    PrevDecl = LookupSingleName(TUScope, SuperClassname, SuperClassLoc,
1025207619Srdivacky                                LookupOrdinaryName);
1026193326Sed    if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
1027193326Sed      Diag(SuperClassLoc, diag::err_redefinition_different_kind)
1028193326Sed        << SuperClassname;
1029193326Sed      Diag(PrevDecl->getLocation(), diag::note_previous_definition);
1030193326Sed    } else {
1031198092Srdivacky      SDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
1032234353Sdim      if (SDecl && !SDecl->hasDefinition())
1033234353Sdim        SDecl = 0;
1034193326Sed      if (!SDecl)
1035193326Sed        Diag(SuperClassLoc, diag::err_undef_superclass)
1036193326Sed          << SuperClassname << ClassName;
1037234353Sdim      else if (IDecl && !declaresSameEntity(IDecl->getSuperClass(), SDecl)) {
1038193326Sed        // This implementation and its interface do not have the same
1039193326Sed        // super class.
1040193326Sed        Diag(SuperClassLoc, diag::err_conflicting_super_class)
1041193326Sed          << SDecl->getDeclName();
1042193326Sed        Diag(SDecl->getLocation(), diag::note_previous_definition);
1043193326Sed      }
1044193326Sed    }
1045193326Sed  }
1046198092Srdivacky
1047193326Sed  if (!IDecl) {
1048193326Sed    // Legacy case of @implementation with no corresponding @interface.
1049193326Sed    // Build, chain & install the interface decl into the identifier.
1050193326Sed
1051193326Sed    // FIXME: Do we support attributes on the @implementation? If so we should
1052193326Sed    // copy them over.
1053198092Srdivacky    IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
1054234353Sdim                                      ClassName, /*PrevDecl=*/0, ClassLoc,
1055234353Sdim                                      true);
1056234353Sdim    IDecl->startDefinition();
1057234353Sdim    if (SDecl) {
1058234353Sdim      IDecl->setSuperClass(SDecl);
1059234353Sdim      IDecl->setSuperClassLoc(SuperClassLoc);
1060234353Sdim      IDecl->setEndOfDefinitionLoc(SuperClassLoc);
1061234353Sdim    } else {
1062234353Sdim      IDecl->setEndOfDefinitionLoc(ClassLoc);
1063234353Sdim    }
1064234353Sdim
1065193326Sed    PushOnScopeChains(IDecl, TUScope);
1066193326Sed  } else {
1067193326Sed    // Mark the interface as being completed, even if it was just as
1068193326Sed    //   @class ....;
1069193326Sed    // declaration; the user cannot reopen it.
1070234353Sdim    if (!IDecl->hasDefinition())
1071234353Sdim      IDecl->startDefinition();
1072193326Sed  }
1073198092Srdivacky
1074198092Srdivacky  ObjCImplementationDecl* IMPDecl =
1075226633Sdim    ObjCImplementationDecl::Create(Context, CurContext, IDecl, SDecl,
1076251662Sdim                                   ClassLoc, AtClassImplLoc, SuperClassLoc);
1077198092Srdivacky
1078193326Sed  if (CheckObjCDeclScope(IMPDecl))
1079226633Sdim    return ActOnObjCContainerStartDefinition(IMPDecl);
1080198092Srdivacky
1081193326Sed  // Check that there is no duplicate implementation of this class.
1082198092Srdivacky  if (IDecl->getImplementation()) {
1083193326Sed    // FIXME: Don't leak everything!
1084193326Sed    Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName;
1085198092Srdivacky    Diag(IDecl->getImplementation()->getLocation(),
1086198092Srdivacky         diag::note_previous_definition);
1087263508Sdim    IMPDecl->setInvalidDecl();
1088198092Srdivacky  } else { // add it to the list.
1089198092Srdivacky    IDecl->setImplementation(IMPDecl);
1090193326Sed    PushOnScopeChains(IMPDecl, TUScope);
1091218893Sdim    // Warn on implementating deprecated class under
1092218893Sdim    // -Wdeprecated-implementations flag.
1093218893Sdim    DiagnoseObjCImplementedDeprecations(*this,
1094218893Sdim                                        dyn_cast<NamedDecl>(IDecl),
1095218893Sdim                                        IMPDecl->getLocation(), 1);
1096198092Srdivacky  }
1097226633Sdim  return ActOnObjCContainerStartDefinition(IMPDecl);
1098193326Sed}
1099193326Sed
1100234353SdimSema::DeclGroupPtrTy
1101234353SdimSema::ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef<Decl *> Decls) {
1102234353Sdim  SmallVector<Decl *, 64> DeclsInGroup;
1103234353Sdim  DeclsInGroup.reserve(Decls.size() + 1);
1104234353Sdim
1105234353Sdim  for (unsigned i = 0, e = Decls.size(); i != e; ++i) {
1106234353Sdim    Decl *Dcl = Decls[i];
1107234353Sdim    if (!Dcl)
1108234353Sdim      continue;
1109234353Sdim    if (Dcl->getDeclContext()->isFileContext())
1110234353Sdim      Dcl->setTopLevelDeclInObjCContainer();
1111234353Sdim    DeclsInGroup.push_back(Dcl);
1112234353Sdim  }
1113234353Sdim
1114234353Sdim  DeclsInGroup.push_back(ObjCImpDecl);
1115234353Sdim
1116263508Sdim  return BuildDeclaratorGroup(DeclsInGroup, false);
1117234353Sdim}
1118234353Sdim
1119193326Sedvoid Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
1120193326Sed                                    ObjCIvarDecl **ivars, unsigned numIvars,
1121193326Sed                                    SourceLocation RBrace) {
1122193326Sed  assert(ImpDecl && "missing implementation decl");
1123193326Sed  ObjCInterfaceDecl* IDecl = ImpDecl->getClassInterface();
1124193326Sed  if (!IDecl)
1125193326Sed    return;
1126239462Sdim  /// Check case of non-existing \@interface decl.
1127239462Sdim  /// (legacy objective-c \@implementation decl without an \@interface decl).
1128193326Sed  /// Add implementations's ivar to the synthesize class's ivar list.
1129193326Sed  if (IDecl->isImplicitInterfaceDecl()) {
1130234353Sdim    IDecl->setEndOfDefinitionLoc(RBrace);
1131204643Srdivacky    // Add ivar's to class's DeclContext.
1132204643Srdivacky    for (unsigned i = 0, e = numIvars; i != e; ++i) {
1133204643Srdivacky      ivars[i]->setLexicalDeclContext(ImpDecl);
1134234353Sdim      IDecl->makeDeclVisibleInContext(ivars[i]);
1135204643Srdivacky      ImpDecl->addDecl(ivars[i]);
1136204643Srdivacky    }
1137204643Srdivacky
1138193326Sed    return;
1139193326Sed  }
1140193326Sed  // If implementation has empty ivar list, just return.
1141193326Sed  if (numIvars == 0)
1142193326Sed    return;
1143198092Srdivacky
1144193326Sed  assert(ivars && "missing @implementation ivars");
1145239462Sdim  if (LangOpts.ObjCRuntime.isNonFragile()) {
1146204643Srdivacky    if (ImpDecl->getSuperClass())
1147204643Srdivacky      Diag(ImpDecl->getLocation(), diag::warn_on_superclass_use);
1148204643Srdivacky    for (unsigned i = 0; i < numIvars; i++) {
1149204643Srdivacky      ObjCIvarDecl* ImplIvar = ivars[i];
1150204643Srdivacky      if (const ObjCIvarDecl *ClsIvar =
1151204643Srdivacky            IDecl->getIvarDecl(ImplIvar->getIdentifier())) {
1152204643Srdivacky        Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration);
1153204643Srdivacky        Diag(ClsIvar->getLocation(), diag::note_previous_definition);
1154204643Srdivacky        continue;
1155204643Srdivacky      }
1156263508Sdim      // Check class extensions (unnamed categories) for duplicate ivars.
1157263508Sdim      for (ObjCInterfaceDecl::visible_extensions_iterator
1158263508Sdim           Ext = IDecl->visible_extensions_begin(),
1159263508Sdim           ExtEnd = IDecl->visible_extensions_end();
1160263508Sdim         Ext != ExtEnd; ++Ext) {
1161263508Sdim        ObjCCategoryDecl *CDecl = *Ext;
1162263508Sdim        if (const ObjCIvarDecl *ClsExtIvar =
1163263508Sdim            CDecl->getIvarDecl(ImplIvar->getIdentifier())) {
1164263508Sdim          Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration);
1165263508Sdim          Diag(ClsExtIvar->getLocation(), diag::note_previous_definition);
1166263508Sdim          continue;
1167263508Sdim        }
1168263508Sdim      }
1169204643Srdivacky      // Instance ivar to Implementation's DeclContext.
1170204643Srdivacky      ImplIvar->setLexicalDeclContext(ImpDecl);
1171234353Sdim      IDecl->makeDeclVisibleInContext(ImplIvar);
1172204643Srdivacky      ImpDecl->addDecl(ImplIvar);
1173204643Srdivacky    }
1174204643Srdivacky    return;
1175204643Srdivacky  }
1176193326Sed  // Check interface's Ivar list against those in the implementation.
1177193326Sed  // names and types must match.
1178193326Sed  //
1179193326Sed  unsigned j = 0;
1180198092Srdivacky  ObjCInterfaceDecl::ivar_iterator
1181193326Sed    IVI = IDecl->ivar_begin(), IVE = IDecl->ivar_end();
1182193326Sed  for (; numIvars > 0 && IVI != IVE; ++IVI) {
1183193326Sed    ObjCIvarDecl* ImplIvar = ivars[j++];
1184193326Sed    ObjCIvarDecl* ClsIvar = *IVI;
1185193326Sed    assert (ImplIvar && "missing implementation ivar");
1186193326Sed    assert (ClsIvar && "missing class ivar");
1187198092Srdivacky
1188193326Sed    // First, make sure the types match.
1189226633Sdim    if (!Context.hasSameType(ImplIvar->getType(), ClsIvar->getType())) {
1190193326Sed      Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type)
1191193326Sed        << ImplIvar->getIdentifier()
1192193326Sed        << ImplIvar->getType() << ClsIvar->getType();
1193193326Sed      Diag(ClsIvar->getLocation(), diag::note_previous_definition);
1194226633Sdim    } else if (ImplIvar->isBitField() && ClsIvar->isBitField() &&
1195226633Sdim               ImplIvar->getBitWidthValue(Context) !=
1196226633Sdim               ClsIvar->getBitWidthValue(Context)) {
1197226633Sdim      Diag(ImplIvar->getBitWidth()->getLocStart(),
1198226633Sdim           diag::err_conflicting_ivar_bitwidth) << ImplIvar->getIdentifier();
1199226633Sdim      Diag(ClsIvar->getBitWidth()->getLocStart(),
1200226633Sdim           diag::note_previous_definition);
1201198092Srdivacky    }
1202193326Sed    // Make sure the names are identical.
1203193326Sed    if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) {
1204193326Sed      Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name)
1205193326Sed        << ImplIvar->getIdentifier() << ClsIvar->getIdentifier();
1206193326Sed      Diag(ClsIvar->getLocation(), diag::note_previous_definition);
1207193326Sed    }
1208193326Sed    --numIvars;
1209193326Sed  }
1210198092Srdivacky
1211193326Sed  if (numIvars > 0)
1212193326Sed    Diag(ivars[j]->getLocation(), diag::err_inconsistant_ivar_count);
1213193326Sed  else if (IVI != IVE)
1214239462Sdim    Diag(IVI->getLocation(), diag::err_inconsistant_ivar_count);
1215193326Sed}
1216193326Sed
1217193326Sedvoid Sema::WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
1218206084Srdivacky                               bool &IncompleteImpl, unsigned DiagID) {
1219224145Sdim  // No point warning no definition of method which is 'unavailable'.
1220249423Sdim  switch (method->getAvailability()) {
1221249423Sdim  case AR_Available:
1222249423Sdim  case AR_Deprecated:
1223249423Sdim    break;
1224249423Sdim
1225249423Sdim      // Don't warn about unavailable or not-yet-introduced methods.
1226249423Sdim  case AR_NotYetIntroduced:
1227249423Sdim  case AR_Unavailable:
1228224145Sdim    return;
1229193326Sed  }
1230249423Sdim
1231249423Sdim  // FIXME: For now ignore 'IncompleteImpl'.
1232249423Sdim  // Previously we grouped all unimplemented methods under a single
1233249423Sdim  // warning, but some users strongly voiced that they would prefer
1234249423Sdim  // separate warnings.  We will give that approach a try, as that
1235249423Sdim  // matches what we do with protocols.
1236249423Sdim
1237249423Sdim  Diag(ImpLoc, DiagID) << method->getDeclName();
1238249423Sdim
1239249423Sdim  // Issue a note to the original declaration.
1240249423Sdim  SourceLocation MethodLoc = method->getLocStart();
1241249423Sdim  if (MethodLoc.isValid())
1242249423Sdim    Diag(MethodLoc, diag::note_method_declared_at) << method;
1243193326Sed}
1244193326Sed
1245218893Sdim/// Determines if type B can be substituted for type A.  Returns true if we can
1246218893Sdim/// guarantee that anything that the user will do to an object of type A can
1247218893Sdim/// also be done to an object of type B.  This is trivially true if the two
1248218893Sdim/// types are the same, or if B is a subclass of A.  It becomes more complex
1249218893Sdim/// in cases where protocols are involved.
1250218893Sdim///
1251218893Sdim/// Object types in Objective-C describe the minimum requirements for an
1252218893Sdim/// object, rather than providing a complete description of a type.  For
1253218893Sdim/// example, if A is a subclass of B, then B* may refer to an instance of A.
1254218893Sdim/// The principle of substitutability means that we may use an instance of A
1255218893Sdim/// anywhere that we may use an instance of B - it will implement all of the
1256218893Sdim/// ivars of B and all of the methods of B.
1257218893Sdim///
1258218893Sdim/// This substitutability is important when type checking methods, because
1259218893Sdim/// the implementation may have stricter type definitions than the interface.
1260218893Sdim/// The interface specifies minimum requirements, but the implementation may
1261218893Sdim/// have more accurate ones.  For example, a method may privately accept
1262218893Sdim/// instances of B, but only publish that it accepts instances of A.  Any
1263218893Sdim/// object passed to it will be type checked against B, and so will implicitly
1264218893Sdim/// by a valid A*.  Similarly, a method may return a subclass of the class that
1265218893Sdim/// it is declared as returning.
1266218893Sdim///
1267218893Sdim/// This is most important when considering subclassing.  A method in a
1268218893Sdim/// subclass must accept any object as an argument that its superclass's
1269218893Sdim/// implementation accepts.  It may, however, accept a more general type
1270218893Sdim/// without breaking substitutability (i.e. you can still use the subclass
1271218893Sdim/// anywhere that you can use the superclass, but not vice versa).  The
1272218893Sdim/// converse requirement applies to return types: the return type for a
1273218893Sdim/// subclass method must be a valid object of the kind that the superclass
1274218893Sdim/// advertises, but it may be specified more accurately.  This avoids the need
1275218893Sdim/// for explicit down-casting by callers.
1276218893Sdim///
1277218893Sdim/// Note: This is a stricter requirement than for assignment.
1278218893Sdimstatic bool isObjCTypeSubstitutable(ASTContext &Context,
1279218893Sdim                                    const ObjCObjectPointerType *A,
1280218893Sdim                                    const ObjCObjectPointerType *B,
1281218893Sdim                                    bool rejectId) {
1282218893Sdim  // Reject a protocol-unqualified id.
1283218893Sdim  if (rejectId && B->isObjCIdType()) return false;
1284218893Sdim
1285218893Sdim  // If B is a qualified id, then A must also be a qualified id and it must
1286218893Sdim  // implement all of the protocols in B.  It may not be a qualified class.
1287218893Sdim  // For example, MyClass<A> can be assigned to id<A>, but MyClass<A> is a
1288218893Sdim  // stricter definition so it is not substitutable for id<A>.
1289218893Sdim  if (B->isObjCQualifiedIdType()) {
1290218893Sdim    return A->isObjCQualifiedIdType() &&
1291218893Sdim           Context.ObjCQualifiedIdTypesAreCompatible(QualType(A, 0),
1292218893Sdim                                                     QualType(B,0),
1293218893Sdim                                                     false);
1294218893Sdim  }
1295218893Sdim
1296218893Sdim  /*
1297218893Sdim  // id is a special type that bypasses type checking completely.  We want a
1298218893Sdim  // warning when it is used in one place but not another.
1299218893Sdim  if (C.isObjCIdType(A) || C.isObjCIdType(B)) return false;
1300218893Sdim
1301218893Sdim
1302218893Sdim  // If B is a qualified id, then A must also be a qualified id (which it isn't
1303218893Sdim  // if we've got this far)
1304218893Sdim  if (B->isObjCQualifiedIdType()) return false;
1305218893Sdim  */
1306218893Sdim
1307218893Sdim  // Now we know that A and B are (potentially-qualified) class types.  The
1308218893Sdim  // normal rules for assignment apply.
1309218893Sdim  return Context.canAssignObjCInterfaces(A, B);
1310218893Sdim}
1311218893Sdim
1312218893Sdimstatic SourceRange getTypeRange(TypeSourceInfo *TSI) {
1313218893Sdim  return (TSI ? TSI->getTypeLoc().getSourceRange() : SourceRange());
1314218893Sdim}
1315218893Sdim
1316226633Sdimstatic bool CheckMethodOverrideReturn(Sema &S,
1317218893Sdim                                      ObjCMethodDecl *MethodImpl,
1318219077Sdim                                      ObjCMethodDecl *MethodDecl,
1319226633Sdim                                      bool IsProtocolMethodDecl,
1320226633Sdim                                      bool IsOverridingMode,
1321226633Sdim                                      bool Warn) {
1322219077Sdim  if (IsProtocolMethodDecl &&
1323219077Sdim      (MethodDecl->getObjCDeclQualifier() !=
1324219077Sdim       MethodImpl->getObjCDeclQualifier())) {
1325226633Sdim    if (Warn) {
1326226633Sdim        S.Diag(MethodImpl->getLocation(),
1327226633Sdim               (IsOverridingMode ?
1328226633Sdim                 diag::warn_conflicting_overriding_ret_type_modifiers
1329226633Sdim                 : diag::warn_conflicting_ret_type_modifiers))
1330226633Sdim          << MethodImpl->getDeclName()
1331226633Sdim          << getTypeRange(MethodImpl->getResultTypeSourceInfo());
1332226633Sdim        S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration)
1333226633Sdim          << getTypeRange(MethodDecl->getResultTypeSourceInfo());
1334226633Sdim    }
1335226633Sdim    else
1336226633Sdim      return false;
1337219077Sdim  }
1338219077Sdim
1339218893Sdim  if (S.Context.hasSameUnqualifiedType(MethodImpl->getResultType(),
1340219077Sdim                                       MethodDecl->getResultType()))
1341226633Sdim    return true;
1342226633Sdim  if (!Warn)
1343226633Sdim    return false;
1344218893Sdim
1345226633Sdim  unsigned DiagID =
1346226633Sdim    IsOverridingMode ? diag::warn_conflicting_overriding_ret_types
1347226633Sdim                     : diag::warn_conflicting_ret_types;
1348218893Sdim
1349218893Sdim  // Mismatches between ObjC pointers go into a different warning
1350218893Sdim  // category, and sometimes they're even completely whitelisted.
1351218893Sdim  if (const ObjCObjectPointerType *ImplPtrTy =
1352218893Sdim        MethodImpl->getResultType()->getAs<ObjCObjectPointerType>()) {
1353218893Sdim    if (const ObjCObjectPointerType *IfacePtrTy =
1354219077Sdim          MethodDecl->getResultType()->getAs<ObjCObjectPointerType>()) {
1355218893Sdim      // Allow non-matching return types as long as they don't violate
1356218893Sdim      // the principle of substitutability.  Specifically, we permit
1357218893Sdim      // return types that are subclasses of the declared return type,
1358218893Sdim      // or that are more-qualified versions of the declared type.
1359218893Sdim      if (isObjCTypeSubstitutable(S.Context, IfacePtrTy, ImplPtrTy, false))
1360226633Sdim        return false;
1361218893Sdim
1362226633Sdim      DiagID =
1363226633Sdim        IsOverridingMode ? diag::warn_non_covariant_overriding_ret_types
1364226633Sdim                          : diag::warn_non_covariant_ret_types;
1365218893Sdim    }
1366218893Sdim  }
1367218893Sdim
1368218893Sdim  S.Diag(MethodImpl->getLocation(), DiagID)
1369218893Sdim    << MethodImpl->getDeclName()
1370219077Sdim    << MethodDecl->getResultType()
1371218893Sdim    << MethodImpl->getResultType()
1372218893Sdim    << getTypeRange(MethodImpl->getResultTypeSourceInfo());
1373226633Sdim  S.Diag(MethodDecl->getLocation(),
1374226633Sdim         IsOverridingMode ? diag::note_previous_declaration
1375226633Sdim                          : diag::note_previous_definition)
1376219077Sdim    << getTypeRange(MethodDecl->getResultTypeSourceInfo());
1377226633Sdim  return false;
1378218893Sdim}
1379218893Sdim
1380226633Sdimstatic bool CheckMethodOverrideParam(Sema &S,
1381218893Sdim                                     ObjCMethodDecl *MethodImpl,
1382219077Sdim                                     ObjCMethodDecl *MethodDecl,
1383218893Sdim                                     ParmVarDecl *ImplVar,
1384219077Sdim                                     ParmVarDecl *IfaceVar,
1385226633Sdim                                     bool IsProtocolMethodDecl,
1386226633Sdim                                     bool IsOverridingMode,
1387226633Sdim                                     bool Warn) {
1388219077Sdim  if (IsProtocolMethodDecl &&
1389219077Sdim      (ImplVar->getObjCDeclQualifier() !=
1390219077Sdim       IfaceVar->getObjCDeclQualifier())) {
1391226633Sdim    if (Warn) {
1392226633Sdim      if (IsOverridingMode)
1393226633Sdim        S.Diag(ImplVar->getLocation(),
1394226633Sdim               diag::warn_conflicting_overriding_param_modifiers)
1395226633Sdim            << getTypeRange(ImplVar->getTypeSourceInfo())
1396226633Sdim            << MethodImpl->getDeclName();
1397226633Sdim      else S.Diag(ImplVar->getLocation(),
1398226633Sdim             diag::warn_conflicting_param_modifiers)
1399226633Sdim          << getTypeRange(ImplVar->getTypeSourceInfo())
1400226633Sdim          << MethodImpl->getDeclName();
1401226633Sdim      S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration)
1402226633Sdim          << getTypeRange(IfaceVar->getTypeSourceInfo());
1403226633Sdim    }
1404226633Sdim    else
1405226633Sdim      return false;
1406219077Sdim  }
1407219077Sdim
1408218893Sdim  QualType ImplTy = ImplVar->getType();
1409218893Sdim  QualType IfaceTy = IfaceVar->getType();
1410219077Sdim
1411218893Sdim  if (S.Context.hasSameUnqualifiedType(ImplTy, IfaceTy))
1412226633Sdim    return true;
1413226633Sdim
1414226633Sdim  if (!Warn)
1415226633Sdim    return false;
1416226633Sdim  unsigned DiagID =
1417226633Sdim    IsOverridingMode ? diag::warn_conflicting_overriding_param_types
1418226633Sdim                     : diag::warn_conflicting_param_types;
1419218893Sdim
1420218893Sdim  // Mismatches between ObjC pointers go into a different warning
1421218893Sdim  // category, and sometimes they're even completely whitelisted.
1422218893Sdim  if (const ObjCObjectPointerType *ImplPtrTy =
1423218893Sdim        ImplTy->getAs<ObjCObjectPointerType>()) {
1424218893Sdim    if (const ObjCObjectPointerType *IfacePtrTy =
1425218893Sdim          IfaceTy->getAs<ObjCObjectPointerType>()) {
1426218893Sdim      // Allow non-matching argument types as long as they don't
1427218893Sdim      // violate the principle of substitutability.  Specifically, the
1428218893Sdim      // implementation must accept any objects that the superclass
1429218893Sdim      // accepts, however it may also accept others.
1430218893Sdim      if (isObjCTypeSubstitutable(S.Context, ImplPtrTy, IfacePtrTy, true))
1431226633Sdim        return false;
1432218893Sdim
1433226633Sdim      DiagID =
1434226633Sdim      IsOverridingMode ? diag::warn_non_contravariant_overriding_param_types
1435226633Sdim                       :  diag::warn_non_contravariant_param_types;
1436218893Sdim    }
1437218893Sdim  }
1438218893Sdim
1439218893Sdim  S.Diag(ImplVar->getLocation(), DiagID)
1440218893Sdim    << getTypeRange(ImplVar->getTypeSourceInfo())
1441218893Sdim    << MethodImpl->getDeclName() << IfaceTy << ImplTy;
1442226633Sdim  S.Diag(IfaceVar->getLocation(),
1443226633Sdim         (IsOverridingMode ? diag::note_previous_declaration
1444226633Sdim                        : diag::note_previous_definition))
1445218893Sdim    << getTypeRange(IfaceVar->getTypeSourceInfo());
1446226633Sdim  return false;
1447218893Sdim}
1448218893Sdim
1449224145Sdim/// In ARC, check whether the conventional meanings of the two methods
1450224145Sdim/// match.  If they don't, it's a hard error.
1451224145Sdimstatic bool checkMethodFamilyMismatch(Sema &S, ObjCMethodDecl *impl,
1452224145Sdim                                      ObjCMethodDecl *decl) {
1453224145Sdim  ObjCMethodFamily implFamily = impl->getMethodFamily();
1454224145Sdim  ObjCMethodFamily declFamily = decl->getMethodFamily();
1455224145Sdim  if (implFamily == declFamily) return false;
1456224145Sdim
1457224145Sdim  // Since conventions are sorted by selector, the only possibility is
1458224145Sdim  // that the types differ enough to cause one selector or the other
1459224145Sdim  // to fall out of the family.
1460224145Sdim  assert(implFamily == OMF_None || declFamily == OMF_None);
1461224145Sdim
1462224145Sdim  // No further diagnostics required on invalid declarations.
1463224145Sdim  if (impl->isInvalidDecl() || decl->isInvalidDecl()) return true;
1464224145Sdim
1465224145Sdim  const ObjCMethodDecl *unmatched = impl;
1466224145Sdim  ObjCMethodFamily family = declFamily;
1467224145Sdim  unsigned errorID = diag::err_arc_lost_method_convention;
1468224145Sdim  unsigned noteID = diag::note_arc_lost_method_convention;
1469224145Sdim  if (declFamily == OMF_None) {
1470224145Sdim    unmatched = decl;
1471224145Sdim    family = implFamily;
1472224145Sdim    errorID = diag::err_arc_gained_method_convention;
1473224145Sdim    noteID = diag::note_arc_gained_method_convention;
1474224145Sdim  }
1475224145Sdim
1476224145Sdim  // Indexes into a %select clause in the diagnostic.
1477224145Sdim  enum FamilySelector {
1478224145Sdim    F_alloc, F_copy, F_mutableCopy = F_copy, F_init, F_new
1479224145Sdim  };
1480224145Sdim  FamilySelector familySelector = FamilySelector();
1481224145Sdim
1482224145Sdim  switch (family) {
1483224145Sdim  case OMF_None: llvm_unreachable("logic error, no method convention");
1484224145Sdim  case OMF_retain:
1485224145Sdim  case OMF_release:
1486224145Sdim  case OMF_autorelease:
1487224145Sdim  case OMF_dealloc:
1488226633Sdim  case OMF_finalize:
1489224145Sdim  case OMF_retainCount:
1490224145Sdim  case OMF_self:
1491224145Sdim  case OMF_performSelector:
1492224145Sdim    // Mismatches for these methods don't change ownership
1493224145Sdim    // conventions, so we don't care.
1494224145Sdim    return false;
1495224145Sdim
1496224145Sdim  case OMF_init: familySelector = F_init; break;
1497224145Sdim  case OMF_alloc: familySelector = F_alloc; break;
1498224145Sdim  case OMF_copy: familySelector = F_copy; break;
1499224145Sdim  case OMF_mutableCopy: familySelector = F_mutableCopy; break;
1500224145Sdim  case OMF_new: familySelector = F_new; break;
1501224145Sdim  }
1502224145Sdim
1503224145Sdim  enum ReasonSelector { R_NonObjectReturn, R_UnrelatedReturn };
1504224145Sdim  ReasonSelector reasonSelector;
1505224145Sdim
1506224145Sdim  // The only reason these methods don't fall within their families is
1507224145Sdim  // due to unusual result types.
1508224145Sdim  if (unmatched->getResultType()->isObjCObjectPointerType()) {
1509224145Sdim    reasonSelector = R_UnrelatedReturn;
1510224145Sdim  } else {
1511224145Sdim    reasonSelector = R_NonObjectReturn;
1512224145Sdim  }
1513224145Sdim
1514263508Sdim  S.Diag(impl->getLocation(), errorID) << int(familySelector) << int(reasonSelector);
1515263508Sdim  S.Diag(decl->getLocation(), noteID) << int(familySelector) << int(reasonSelector);
1516224145Sdim
1517224145Sdim  return true;
1518224145Sdim}
1519224145Sdim
1520193326Sedvoid Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl,
1521219077Sdim                                       ObjCMethodDecl *MethodDecl,
1522219077Sdim                                       bool IsProtocolMethodDecl) {
1523234353Sdim  if (getLangOpts().ObjCAutoRefCount &&
1524224145Sdim      checkMethodFamilyMismatch(*this, ImpMethodDecl, MethodDecl))
1525224145Sdim    return;
1526224145Sdim
1527219077Sdim  CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl,
1528226633Sdim                            IsProtocolMethodDecl, false,
1529226633Sdim                            true);
1530198092Srdivacky
1531193326Sed  for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
1532239462Sdim       IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(),
1533239462Sdim       EF = MethodDecl->param_end();
1534239462Sdim       IM != EM && IF != EF; ++IM, ++IF) {
1535219077Sdim    CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl, *IM, *IF,
1536226633Sdim                             IsProtocolMethodDecl, false, true);
1537226633Sdim  }
1538198092Srdivacky
1539219077Sdim  if (ImpMethodDecl->isVariadic() != MethodDecl->isVariadic()) {
1540226633Sdim    Diag(ImpMethodDecl->getLocation(),
1541226633Sdim         diag::warn_conflicting_variadic);
1542219077Sdim    Diag(MethodDecl->getLocation(), diag::note_previous_declaration);
1543208600Srdivacky  }
1544193326Sed}
1545193326Sed
1546226633Sdimvoid Sema::CheckConflictingOverridingMethod(ObjCMethodDecl *Method,
1547226633Sdim                                       ObjCMethodDecl *Overridden,
1548226633Sdim                                       bool IsProtocolMethodDecl) {
1549226633Sdim
1550226633Sdim  CheckMethodOverrideReturn(*this, Method, Overridden,
1551226633Sdim                            IsProtocolMethodDecl, true,
1552226633Sdim                            true);
1553226633Sdim
1554226633Sdim  for (ObjCMethodDecl::param_iterator IM = Method->param_begin(),
1555239462Sdim       IF = Overridden->param_begin(), EM = Method->param_end(),
1556239462Sdim       EF = Overridden->param_end();
1557239462Sdim       IM != EM && IF != EF; ++IM, ++IF) {
1558226633Sdim    CheckMethodOverrideParam(*this, Method, Overridden, *IM, *IF,
1559226633Sdim                             IsProtocolMethodDecl, true, true);
1560226633Sdim  }
1561226633Sdim
1562226633Sdim  if (Method->isVariadic() != Overridden->isVariadic()) {
1563226633Sdim    Diag(Method->getLocation(),
1564226633Sdim         diag::warn_conflicting_overriding_variadic);
1565226633Sdim    Diag(Overridden->getLocation(), diag::note_previous_declaration);
1566226633Sdim  }
1567226633Sdim}
1568226633Sdim
1569226633Sdim/// WarnExactTypedMethods - This routine issues a warning if method
1570226633Sdim/// implementation declaration matches exactly that of its declaration.
1571226633Sdimvoid Sema::WarnExactTypedMethods(ObjCMethodDecl *ImpMethodDecl,
1572226633Sdim                                 ObjCMethodDecl *MethodDecl,
1573226633Sdim                                 bool IsProtocolMethodDecl) {
1574226633Sdim  // don't issue warning when protocol method is optional because primary
1575226633Sdim  // class is not required to implement it and it is safe for protocol
1576226633Sdim  // to implement it.
1577226633Sdim  if (MethodDecl->getImplementationControl() == ObjCMethodDecl::Optional)
1578226633Sdim    return;
1579226633Sdim  // don't issue warning when primary class's method is
1580226633Sdim  // depecated/unavailable.
1581226633Sdim  if (MethodDecl->hasAttr<UnavailableAttr>() ||
1582226633Sdim      MethodDecl->hasAttr<DeprecatedAttr>())
1583226633Sdim    return;
1584226633Sdim
1585226633Sdim  bool match = CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl,
1586226633Sdim                                      IsProtocolMethodDecl, false, false);
1587226633Sdim  if (match)
1588226633Sdim    for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
1589239462Sdim         IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(),
1590239462Sdim         EF = MethodDecl->param_end();
1591239462Sdim         IM != EM && IF != EF; ++IM, ++IF) {
1592226633Sdim      match = CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl,
1593226633Sdim                                       *IM, *IF,
1594226633Sdim                                       IsProtocolMethodDecl, false, false);
1595226633Sdim      if (!match)
1596226633Sdim        break;
1597226633Sdim    }
1598226633Sdim  if (match)
1599226633Sdim    match = (ImpMethodDecl->isVariadic() == MethodDecl->isVariadic());
1600226633Sdim  if (match)
1601226633Sdim    match = !(MethodDecl->isClassMethod() &&
1602226633Sdim              MethodDecl->getSelector() == GetNullarySelector("load", Context));
1603226633Sdim
1604226633Sdim  if (match) {
1605226633Sdim    Diag(ImpMethodDecl->getLocation(),
1606226633Sdim         diag::warn_category_method_impl_match);
1607234353Sdim    Diag(MethodDecl->getLocation(), diag::note_method_declared_at)
1608234353Sdim      << MethodDecl->getDeclName();
1609226633Sdim  }
1610226633Sdim}
1611226633Sdim
1612193326Sed/// FIXME: Type hierarchies in Objective-C can be deep. We could most likely
1613193326Sed/// improve the efficiency of selector lookups and type checking by associating
1614193326Sed/// with each protocol / interface / category the flattened instance tables. If
1615193326Sed/// we used an immutable set to keep the table then it wouldn't add significant
1616193326Sed/// memory cost and it would be handy for lookups.
1617193326Sed
1618193326Sed/// CheckProtocolMethodDefs - This routine checks unimplemented methods
1619193326Sed/// Declared in protocol, and those referenced by it.
1620193326Sedvoid Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
1621193326Sed                                   ObjCProtocolDecl *PDecl,
1622193326Sed                                   bool& IncompleteImpl,
1623239462Sdim                                   const SelectorSet &InsMap,
1624239462Sdim                                   const SelectorSet &ClsMap,
1625206084Srdivacky                                   ObjCContainerDecl *CDecl) {
1626234353Sdim  ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl);
1627234353Sdim  ObjCInterfaceDecl *IDecl = C ? C->getClassInterface()
1628234353Sdim                               : dyn_cast<ObjCInterfaceDecl>(CDecl);
1629206084Srdivacky  assert (IDecl && "CheckProtocolMethodDefs - IDecl is null");
1630206084Srdivacky
1631193326Sed  ObjCInterfaceDecl *Super = IDecl->getSuperClass();
1632193326Sed  ObjCInterfaceDecl *NSIDecl = 0;
1633239462Sdim  if (getLangOpts().ObjCRuntime.isNeXTFamily()) {
1634198092Srdivacky    // check to see if class implements forwardInvocation method and objects
1635198092Srdivacky    // of this class are derived from 'NSProxy' so that to forward requests
1636193326Sed    // from one object to another.
1637198092Srdivacky    // Under such conditions, which means that every method possible is
1638198092Srdivacky    // implemented in the class, we should not issue "Method definition not
1639193326Sed    // found" warnings.
1640193326Sed    // FIXME: Use a general GetUnarySelector method for this.
1641193326Sed    IdentifierInfo* II = &Context.Idents.get("forwardInvocation");
1642193326Sed    Selector fISelector = Context.Selectors.getSelector(1, &II);
1643193326Sed    if (InsMap.count(fISelector))
1644193326Sed      // Is IDecl derived from 'NSProxy'? If so, no instance methods
1645193326Sed      // need be implemented in the implementation.
1646193326Sed      NSIDecl = IDecl->lookupInheritedClass(&Context.Idents.get("NSProxy"));
1647193326Sed  }
1648198092Srdivacky
1649249423Sdim  // If this is a forward protocol declaration, get its definition.
1650249423Sdim  if (!PDecl->isThisDeclarationADefinition() &&
1651249423Sdim      PDecl->getDefinition())
1652249423Sdim    PDecl = PDecl->getDefinition();
1653249423Sdim
1654193326Sed  // If a method lookup fails locally we still need to look and see if
1655193326Sed  // the method was implemented by a base class or an inherited
1656193326Sed  // protocol. This lookup is slow, but occurs rarely in correct code
1657193326Sed  // and otherwise would terminate in a warning.
1658193326Sed
1659193326Sed  // check unimplemented instance methods.
1660193326Sed  if (!NSIDecl)
1661198092Srdivacky    for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
1662195341Sed         E = PDecl->instmeth_end(); I != E; ++I) {
1663193326Sed      ObjCMethodDecl *method = *I;
1664198092Srdivacky      if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
1665243830Sdim          !method->isPropertyAccessor() &&
1666243830Sdim          !InsMap.count(method->getSelector()) &&
1667243830Sdim          (!Super || !Super->lookupInstanceMethod(method->getSelector()))) {
1668234353Sdim            // If a method is not implemented in the category implementation but
1669234353Sdim            // has been declared in its primary class, superclass,
1670234353Sdim            // or in one of their protocols, no need to issue the warning.
1671234353Sdim            // This is because method will be implemented in the primary class
1672234353Sdim            // or one of its super class implementation.
1673234353Sdim
1674193326Sed            // Ugly, but necessary. Method declared in protcol might have
1675193326Sed            // have been synthesized due to a property declared in the class which
1676193326Sed            // uses the protocol.
1677234353Sdim            if (ObjCMethodDecl *MethodInClass =
1678234353Sdim                  IDecl->lookupInstanceMethod(method->getSelector(),
1679234353Sdim                                              true /*shallowCategoryLookup*/))
1680243830Sdim              if (C || MethodInClass->isPropertyAccessor())
1681234353Sdim                continue;
1682234353Sdim            unsigned DIAG = diag::warn_unimplemented_protocol_method;
1683234353Sdim            if (Diags.getDiagnosticLevel(DIAG, ImpLoc)
1684234353Sdim                != DiagnosticsEngine::Ignored) {
1685234353Sdim              WarnUndefinedMethod(ImpLoc, method, IncompleteImpl, DIAG);
1686234353Sdim              Diag(CDecl->getLocation(), diag::note_required_for_protocol_at)
1687234353Sdim                << PDecl->getDeclName();
1688206084Srdivacky            }
1689193326Sed          }
1690193326Sed    }
1691193326Sed  // check unimplemented class methods
1692198092Srdivacky  for (ObjCProtocolDecl::classmeth_iterator
1693195341Sed         I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
1694193326Sed       I != E; ++I) {
1695193326Sed    ObjCMethodDecl *method = *I;
1696193326Sed    if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
1697193326Sed        !ClsMap.count(method->getSelector()) &&
1698206084Srdivacky        (!Super || !Super->lookupClassMethod(method->getSelector()))) {
1699234353Sdim      // See above comment for instance method lookups.
1700234353Sdim      if (C && IDecl->lookupClassMethod(method->getSelector(),
1701234353Sdim                                        true /*shallowCategoryLookup*/))
1702234353Sdim        continue;
1703206084Srdivacky      unsigned DIAG = diag::warn_unimplemented_protocol_method;
1704226633Sdim      if (Diags.getDiagnosticLevel(DIAG, ImpLoc) !=
1705226633Sdim            DiagnosticsEngine::Ignored) {
1706206084Srdivacky        WarnUndefinedMethod(ImpLoc, method, IncompleteImpl, DIAG);
1707206084Srdivacky        Diag(IDecl->getLocation(), diag::note_required_for_protocol_at) <<
1708206084Srdivacky          PDecl->getDeclName();
1709206084Srdivacky      }
1710206084Srdivacky    }
1711193326Sed  }
1712193326Sed  // Check on this protocols's referenced protocols, recursively.
1713193326Sed  for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
1714193326Sed       E = PDecl->protocol_end(); PI != E; ++PI)
1715234353Sdim    CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap, CDecl);
1716193326Sed}
1717193326Sed
1718224145Sdim/// MatchAllMethodDeclarations - Check methods declared in interface
1719193326Sed/// or protocol against those declared in their implementations.
1720193326Sed///
1721239462Sdimvoid Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap,
1722239462Sdim                                      const SelectorSet &ClsMap,
1723239462Sdim                                      SelectorSet &InsMapSeen,
1724239462Sdim                                      SelectorSet &ClsMapSeen,
1725193326Sed                                      ObjCImplDecl* IMPDecl,
1726193326Sed                                      ObjCContainerDecl* CDecl,
1727193326Sed                                      bool &IncompleteImpl,
1728226633Sdim                                      bool ImmediateClass,
1729234353Sdim                                      bool WarnCategoryMethodImpl) {
1730193326Sed  // Check and see if instance methods in class interface have been
1731193326Sed  // implemented in the implementation class. If so, their types match.
1732195341Sed  for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(),
1733195341Sed       E = CDecl->instmeth_end(); I != E; ++I) {
1734263508Sdim    if (!InsMapSeen.insert((*I)->getSelector()))
1735263508Sdim      continue;
1736243830Sdim    if (!(*I)->isPropertyAccessor() &&
1737193326Sed        !InsMap.count((*I)->getSelector())) {
1738193326Sed      if (ImmediateClass)
1739206084Srdivacky        WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl,
1740249423Sdim                            diag::warn_undef_method_impl);
1741193326Sed      continue;
1742198092Srdivacky    } else {
1743198092Srdivacky      ObjCMethodDecl *ImpMethodDecl =
1744226633Sdim        IMPDecl->getInstanceMethod((*I)->getSelector());
1745226633Sdim      assert(CDecl->getInstanceMethod((*I)->getSelector()) &&
1746226633Sdim             "Expected to find the method through lookup as well");
1747226633Sdim      ObjCMethodDecl *MethodDecl = *I;
1748193326Sed      // ImpMethodDecl may be null as in a @dynamic property.
1749226633Sdim      if (ImpMethodDecl) {
1750234353Sdim        if (!WarnCategoryMethodImpl)
1751226633Sdim          WarnConflictingTypedMethods(ImpMethodDecl, MethodDecl,
1752226633Sdim                                      isa<ObjCProtocolDecl>(CDecl));
1753243830Sdim        else if (!MethodDecl->isPropertyAccessor())
1754226633Sdim          WarnExactTypedMethods(ImpMethodDecl, MethodDecl,
1755234353Sdim                                isa<ObjCProtocolDecl>(CDecl));
1756226633Sdim      }
1757193326Sed    }
1758193326Sed  }
1759198092Srdivacky
1760193326Sed  // Check and see if class methods in class interface have been
1761193326Sed  // implemented in the implementation class. If so, their types match.
1762263508Sdim  for (ObjCInterfaceDecl::classmeth_iterator I = CDecl->classmeth_begin(),
1763263508Sdim                                             E = CDecl->classmeth_end();
1764263508Sdim       I != E; ++I) {
1765263508Sdim    if (!ClsMapSeen.insert((*I)->getSelector()))
1766263508Sdim      continue;
1767193326Sed    if (!ClsMap.count((*I)->getSelector())) {
1768193326Sed      if (ImmediateClass)
1769206084Srdivacky        WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl,
1770249423Sdim                            diag::warn_undef_method_impl);
1771198092Srdivacky    } else {
1772195341Sed      ObjCMethodDecl *ImpMethodDecl =
1773195341Sed        IMPDecl->getClassMethod((*I)->getSelector());
1774226633Sdim      assert(CDecl->getClassMethod((*I)->getSelector()) &&
1775226633Sdim             "Expected to find the method through lookup as well");
1776226633Sdim      ObjCMethodDecl *MethodDecl = *I;
1777234353Sdim      if (!WarnCategoryMethodImpl)
1778226633Sdim        WarnConflictingTypedMethods(ImpMethodDecl, MethodDecl,
1779226633Sdim                                    isa<ObjCProtocolDecl>(CDecl));
1780226633Sdim      else
1781226633Sdim        WarnExactTypedMethods(ImpMethodDecl, MethodDecl,
1782234353Sdim                              isa<ObjCProtocolDecl>(CDecl));
1783193326Sed    }
1784193326Sed  }
1785218893Sdim
1786263508Sdim  if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl> (CDecl)) {
1787263508Sdim    // Also, check for methods declared in protocols inherited by
1788263508Sdim    // this protocol.
1789263508Sdim    for (ObjCProtocolDecl::protocol_iterator
1790263508Sdim          PI = PD->protocol_begin(), E = PD->protocol_end(); PI != E; ++PI)
1791263508Sdim      MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1792263508Sdim                                 IMPDecl, (*PI), IncompleteImpl, false,
1793263508Sdim                                 WarnCategoryMethodImpl);
1794263508Sdim  }
1795263508Sdim
1796193326Sed  if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
1797243830Sdim    // when checking that methods in implementation match their declaration,
1798243830Sdim    // i.e. when WarnCategoryMethodImpl is false, check declarations in class
1799243830Sdim    // extension; as well as those in categories.
1800249423Sdim    if (!WarnCategoryMethodImpl) {
1801249423Sdim      for (ObjCInterfaceDecl::visible_categories_iterator
1802249423Sdim             Cat = I->visible_categories_begin(),
1803249423Sdim           CatEnd = I->visible_categories_end();
1804249423Sdim           Cat != CatEnd; ++Cat) {
1805243830Sdim        MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1806249423Sdim                                   IMPDecl, *Cat, IncompleteImpl, false,
1807243830Sdim                                   WarnCategoryMethodImpl);
1808249423Sdim      }
1809249423Sdim    } else {
1810243830Sdim      // Also methods in class extensions need be looked at next.
1811249423Sdim      for (ObjCInterfaceDecl::visible_extensions_iterator
1812249423Sdim             Ext = I->visible_extensions_begin(),
1813249423Sdim             ExtEnd = I->visible_extensions_end();
1814249423Sdim           Ext != ExtEnd; ++Ext) {
1815243830Sdim        MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1816249423Sdim                                   IMPDecl, *Ext, IncompleteImpl, false,
1817243830Sdim                                   WarnCategoryMethodImpl);
1818249423Sdim      }
1819249423Sdim    }
1820249423Sdim
1821193326Sed    // Check for any implementation of a methods declared in protocol.
1822212904Sdim    for (ObjCInterfaceDecl::all_protocol_iterator
1823212904Sdim          PI = I->all_referenced_protocol_begin(),
1824212904Sdim          E = I->all_referenced_protocol_end(); PI != E; ++PI)
1825198092Srdivacky      MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1826198092Srdivacky                                 IMPDecl,
1827234353Sdim                                 (*PI), IncompleteImpl, false,
1828234353Sdim                                 WarnCategoryMethodImpl);
1829226633Sdim
1830226633Sdim    // FIXME. For now, we are not checking for extact match of methods
1831226633Sdim    // in category implementation and its primary class's super class.
1832234353Sdim    if (!WarnCategoryMethodImpl && I->getSuperClass())
1833193326Sed      MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1834198092Srdivacky                                 IMPDecl,
1835193326Sed                                 I->getSuperClass(), IncompleteImpl, false);
1836193326Sed  }
1837193326Sed}
1838193326Sed
1839226633Sdim/// CheckCategoryVsClassMethodMatches - Checks that methods implemented in
1840226633Sdim/// category matches with those implemented in its primary class and
1841226633Sdim/// warns each time an exact match is found.
1842226633Sdimvoid Sema::CheckCategoryVsClassMethodMatches(
1843226633Sdim                                  ObjCCategoryImplDecl *CatIMPDecl) {
1844239462Sdim  SelectorSet InsMap, ClsMap;
1845226633Sdim
1846226633Sdim  for (ObjCImplementationDecl::instmeth_iterator
1847226633Sdim       I = CatIMPDecl->instmeth_begin(),
1848226633Sdim       E = CatIMPDecl->instmeth_end(); I!=E; ++I)
1849226633Sdim    InsMap.insert((*I)->getSelector());
1850226633Sdim
1851226633Sdim  for (ObjCImplementationDecl::classmeth_iterator
1852226633Sdim       I = CatIMPDecl->classmeth_begin(),
1853226633Sdim       E = CatIMPDecl->classmeth_end(); I != E; ++I)
1854226633Sdim    ClsMap.insert((*I)->getSelector());
1855226633Sdim  if (InsMap.empty() && ClsMap.empty())
1856226633Sdim    return;
1857226633Sdim
1858226633Sdim  // Get category's primary class.
1859226633Sdim  ObjCCategoryDecl *CatDecl = CatIMPDecl->getCategoryDecl();
1860226633Sdim  if (!CatDecl)
1861226633Sdim    return;
1862226633Sdim  ObjCInterfaceDecl *IDecl = CatDecl->getClassInterface();
1863226633Sdim  if (!IDecl)
1864226633Sdim    return;
1865239462Sdim  SelectorSet InsMapSeen, ClsMapSeen;
1866226633Sdim  bool IncompleteImpl = false;
1867226633Sdim  MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1868226633Sdim                             CatIMPDecl, IDecl,
1869234353Sdim                             IncompleteImpl, false,
1870234353Sdim                             true /*WarnCategoryMethodImpl*/);
1871226633Sdim}
1872226633Sdim
1873208600Srdivackyvoid Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
1874198092Srdivacky                                     ObjCContainerDecl* CDecl,
1875193326Sed                                     bool IncompleteImpl) {
1876239462Sdim  SelectorSet InsMap;
1877193326Sed  // Check and see if instance methods in class interface have been
1878193326Sed  // implemented in the implementation class.
1879198092Srdivacky  for (ObjCImplementationDecl::instmeth_iterator
1880195341Sed         I = IMPDecl->instmeth_begin(), E = IMPDecl->instmeth_end(); I!=E; ++I)
1881193326Sed    InsMap.insert((*I)->getSelector());
1882198092Srdivacky
1883193326Sed  // Check and see if properties declared in the interface have either 1)
1884193326Sed  // an implementation or 2) there is a @synthesize/@dynamic implementation
1885193326Sed  // of the property in the @implementation.
1886234353Sdim  if (const ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl))
1887239462Sdim    if  (!(LangOpts.ObjCDefaultSynthProperties &&
1888239462Sdim           LangOpts.ObjCRuntime.isNonFragile()) ||
1889239462Sdim         IDecl->isObjCRequiresPropertyDefs())
1890251662Sdim      DiagnoseUnimplementedProperties(S, IMPDecl, CDecl);
1891202879Srdivacky
1892239462Sdim  SelectorSet ClsMap;
1893198092Srdivacky  for (ObjCImplementationDecl::classmeth_iterator
1894195341Sed       I = IMPDecl->classmeth_begin(),
1895195341Sed       E = IMPDecl->classmeth_end(); I != E; ++I)
1896193326Sed    ClsMap.insert((*I)->getSelector());
1897198092Srdivacky
1898193326Sed  // Check for type conflict of methods declared in a class/protocol and
1899193326Sed  // its implementation; if any.
1900239462Sdim  SelectorSet InsMapSeen, ClsMapSeen;
1901198092Srdivacky  MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1902198092Srdivacky                             IMPDecl, CDecl,
1903193326Sed                             IncompleteImpl, true);
1904226633Sdim
1905226633Sdim  // check all methods implemented in category against those declared
1906226633Sdim  // in its primary class.
1907226633Sdim  if (ObjCCategoryImplDecl *CatDecl =
1908226633Sdim        dyn_cast<ObjCCategoryImplDecl>(IMPDecl))
1909226633Sdim    CheckCategoryVsClassMethodMatches(CatDecl);
1910198092Srdivacky
1911193326Sed  // Check the protocol list for unimplemented methods in the @implementation
1912193326Sed  // class.
1913193326Sed  // Check and see if class methods in class interface have been
1914193326Sed  // implemented in the implementation class.
1915198092Srdivacky
1916193326Sed  if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
1917212904Sdim    for (ObjCInterfaceDecl::all_protocol_iterator
1918212904Sdim          PI = I->all_referenced_protocol_begin(),
1919212904Sdim          E = I->all_referenced_protocol_end(); PI != E; ++PI)
1920198092Srdivacky      CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
1921193326Sed                              InsMap, ClsMap, I);
1922193326Sed    // Check class extensions (unnamed categories)
1923249423Sdim    for (ObjCInterfaceDecl::visible_extensions_iterator
1924249423Sdim           Ext = I->visible_extensions_begin(),
1925249423Sdim           ExtEnd = I->visible_extensions_end();
1926249423Sdim         Ext != ExtEnd; ++Ext) {
1927249423Sdim      ImplMethodsVsClassMethods(S, IMPDecl, *Ext, IncompleteImpl);
1928249423Sdim    }
1929193326Sed  } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
1930198092Srdivacky    // For extended class, unimplemented methods in its protocols will
1931198092Srdivacky    // be reported in the primary class.
1932203955Srdivacky    if (!C->IsClassExtension()) {
1933198092Srdivacky      for (ObjCCategoryDecl::protocol_iterator PI = C->protocol_begin(),
1934198092Srdivacky           E = C->protocol_end(); PI != E; ++PI)
1935198092Srdivacky        CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
1936206084Srdivacky                                InsMap, ClsMap, CDecl);
1937251662Sdim      DiagnoseUnimplementedProperties(S, IMPDecl, CDecl);
1938202879Srdivacky    }
1939193326Sed  } else
1940226633Sdim    llvm_unreachable("invalid ObjCContainerDecl type.");
1941193326Sed}
1942193326Sed
1943198092Srdivacky/// ActOnForwardClassDeclaration -
1944226633SdimSema::DeclGroupPtrTy
1945193326SedSema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
1946193326Sed                                   IdentifierInfo **IdentList,
1947199482Srdivacky                                   SourceLocation *IdentLocs,
1948193326Sed                                   unsigned NumElts) {
1949226633Sdim  SmallVector<Decl *, 8> DeclsInGroup;
1950193326Sed  for (unsigned i = 0; i != NumElts; ++i) {
1951193326Sed    // Check for another declaration kind with the same name.
1952198092Srdivacky    NamedDecl *PrevDecl
1953207619Srdivacky      = LookupSingleName(TUScope, IdentList[i], IdentLocs[i],
1954207619Srdivacky                         LookupOrdinaryName, ForRedeclaration);
1955193326Sed    if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
1956193326Sed      // GCC apparently allows the following idiom:
1957193326Sed      //
1958193326Sed      // typedef NSObject < XCElementTogglerP > XCElementToggler;
1959193326Sed      // @class XCElementToggler;
1960193326Sed      //
1961234353Sdim      // Here we have chosen to ignore the forward class declaration
1962234353Sdim      // with a warning. Since this is the implied behavior.
1963221345Sdim      TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(PrevDecl);
1964208600Srdivacky      if (!TDD || !TDD->getUnderlyingType()->isObjCObjectType()) {
1965193326Sed        Diag(AtClassLoc, diag::err_redefinition_different_kind) << IdentList[i];
1966193326Sed        Diag(PrevDecl->getLocation(), diag::note_previous_definition);
1967208600Srdivacky      } else {
1968198092Srdivacky        // a forward class declaration matching a typedef name of a class refers
1969234353Sdim        // to the underlying class. Just ignore the forward class with a warning
1970234353Sdim        // as this will force the intended behavior which is to lookup the typedef
1971234353Sdim        // name.
1972234353Sdim        if (isa<ObjCObjectType>(TDD->getUnderlyingType())) {
1973234353Sdim          Diag(AtClassLoc, diag::warn_forward_class_redefinition) << IdentList[i];
1974234353Sdim          Diag(PrevDecl->getLocation(), diag::note_previous_definition);
1975234353Sdim          continue;
1976234353Sdim        }
1977193326Sed      }
1978193326Sed    }
1979234353Sdim
1980234353Sdim    // Create a declaration to describe this forward declaration.
1981234353Sdim    ObjCInterfaceDecl *PrevIDecl
1982234353Sdim      = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
1983263508Sdim
1984263508Sdim    IdentifierInfo *ClassName = IdentList[i];
1985263508Sdim    if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) {
1986263508Sdim      // A previous decl with a different name is because of
1987263508Sdim      // @compatibility_alias, for example:
1988263508Sdim      // \code
1989263508Sdim      //   @class NewImage;
1990263508Sdim      //   @compatibility_alias OldImage NewImage;
1991263508Sdim      // \endcode
1992263508Sdim      // A lookup for 'OldImage' will return the 'NewImage' decl.
1993263508Sdim      //
1994263508Sdim      // In such a case use the real declaration name, instead of the alias one,
1995263508Sdim      // otherwise we will break IdentifierResolver and redecls-chain invariants.
1996263508Sdim      // FIXME: If necessary, add a bit to indicate that this ObjCInterfaceDecl
1997263508Sdim      // has been aliased.
1998263508Sdim      ClassName = PrevIDecl->getIdentifier();
1999263508Sdim    }
2000263508Sdim
2001234353Sdim    ObjCInterfaceDecl *IDecl
2002234353Sdim      = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
2003263508Sdim                                  ClassName, PrevIDecl, IdentLocs[i]);
2004234353Sdim    IDecl->setAtEndRange(IdentLocs[i]);
2005234353Sdim
2006234353Sdim    PushOnScopeChains(IDecl, TUScope);
2007234353Sdim    CheckObjCDeclScope(IDecl);
2008234353Sdim    DeclsInGroup.push_back(IDecl);
2009193326Sed  }
2010263508Sdim
2011263508Sdim  return BuildDeclaratorGroup(DeclsInGroup, false);
2012193326Sed}
2013193326Sed
2014224145Sdimstatic bool tryMatchRecordTypes(ASTContext &Context,
2015224145Sdim                                Sema::MethodMatchStrategy strategy,
2016224145Sdim                                const Type *left, const Type *right);
2017193326Sed
2018224145Sdimstatic bool matchTypes(ASTContext &Context, Sema::MethodMatchStrategy strategy,
2019224145Sdim                       QualType leftQT, QualType rightQT) {
2020224145Sdim  const Type *left =
2021224145Sdim    Context.getCanonicalType(leftQT).getUnqualifiedType().getTypePtr();
2022224145Sdim  const Type *right =
2023224145Sdim    Context.getCanonicalType(rightQT).getUnqualifiedType().getTypePtr();
2024224145Sdim
2025224145Sdim  if (left == right) return true;
2026224145Sdim
2027224145Sdim  // If we're doing a strict match, the types have to match exactly.
2028224145Sdim  if (strategy == Sema::MMS_strict) return false;
2029224145Sdim
2030224145Sdim  if (left->isIncompleteType() || right->isIncompleteType()) return false;
2031224145Sdim
2032224145Sdim  // Otherwise, use this absurdly complicated algorithm to try to
2033224145Sdim  // validate the basic, low-level compatibility of the two types.
2034224145Sdim
2035224145Sdim  // As a minimum, require the sizes and alignments to match.
2036224145Sdim  if (Context.getTypeInfo(left) != Context.getTypeInfo(right))
2037224145Sdim    return false;
2038224145Sdim
2039224145Sdim  // Consider all the kinds of non-dependent canonical types:
2040224145Sdim  // - functions and arrays aren't possible as return and parameter types
2041224145Sdim
2042224145Sdim  // - vector types of equal size can be arbitrarily mixed
2043224145Sdim  if (isa<VectorType>(left)) return isa<VectorType>(right);
2044224145Sdim  if (isa<VectorType>(right)) return false;
2045224145Sdim
2046224145Sdim  // - references should only match references of identical type
2047224145Sdim  // - structs, unions, and Objective-C objects must match more-or-less
2048224145Sdim  //   exactly
2049224145Sdim  // - everything else should be a scalar
2050224145Sdim  if (!left->isScalarType() || !right->isScalarType())
2051224145Sdim    return tryMatchRecordTypes(Context, strategy, left, right);
2052224145Sdim
2053226633Sdim  // Make scalars agree in kind, except count bools as chars, and group
2054226633Sdim  // all non-member pointers together.
2055224145Sdim  Type::ScalarTypeKind leftSK = left->getScalarTypeKind();
2056224145Sdim  Type::ScalarTypeKind rightSK = right->getScalarTypeKind();
2057224145Sdim  if (leftSK == Type::STK_Bool) leftSK = Type::STK_Integral;
2058224145Sdim  if (rightSK == Type::STK_Bool) rightSK = Type::STK_Integral;
2059226633Sdim  if (leftSK == Type::STK_CPointer || leftSK == Type::STK_BlockPointer)
2060226633Sdim    leftSK = Type::STK_ObjCObjectPointer;
2061226633Sdim  if (rightSK == Type::STK_CPointer || rightSK == Type::STK_BlockPointer)
2062226633Sdim    rightSK = Type::STK_ObjCObjectPointer;
2063224145Sdim
2064224145Sdim  // Note that data member pointers and function member pointers don't
2065224145Sdim  // intermix because of the size differences.
2066224145Sdim
2067224145Sdim  return (leftSK == rightSK);
2068224145Sdim}
2069224145Sdim
2070224145Sdimstatic bool tryMatchRecordTypes(ASTContext &Context,
2071224145Sdim                                Sema::MethodMatchStrategy strategy,
2072224145Sdim                                const Type *lt, const Type *rt) {
2073224145Sdim  assert(lt && rt && lt != rt);
2074224145Sdim
2075224145Sdim  if (!isa<RecordType>(lt) || !isa<RecordType>(rt)) return false;
2076224145Sdim  RecordDecl *left = cast<RecordType>(lt)->getDecl();
2077224145Sdim  RecordDecl *right = cast<RecordType>(rt)->getDecl();
2078224145Sdim
2079224145Sdim  // Require union-hood to match.
2080224145Sdim  if (left->isUnion() != right->isUnion()) return false;
2081224145Sdim
2082224145Sdim  // Require an exact match if either is non-POD.
2083224145Sdim  if ((isa<CXXRecordDecl>(left) && !cast<CXXRecordDecl>(left)->isPOD()) ||
2084224145Sdim      (isa<CXXRecordDecl>(right) && !cast<CXXRecordDecl>(right)->isPOD()))
2085224145Sdim    return false;
2086224145Sdim
2087224145Sdim  // Require size and alignment to match.
2088224145Sdim  if (Context.getTypeInfo(lt) != Context.getTypeInfo(rt)) return false;
2089224145Sdim
2090224145Sdim  // Require fields to match.
2091224145Sdim  RecordDecl::field_iterator li = left->field_begin(), le = left->field_end();
2092224145Sdim  RecordDecl::field_iterator ri = right->field_begin(), re = right->field_end();
2093224145Sdim  for (; li != le && ri != re; ++li, ++ri) {
2094224145Sdim    if (!matchTypes(Context, strategy, li->getType(), ri->getType()))
2095224145Sdim      return false;
2096224145Sdim  }
2097224145Sdim  return (li == le && ri == re);
2098224145Sdim}
2099224145Sdim
2100193326Sed/// MatchTwoMethodDeclarations - Checks that two methods have matching type and
2101193326Sed/// returns true, or false, accordingly.
2102193326Sed/// TODO: Handle protocol list; such as id<p1,p2> in type comparisons
2103224145Sdimbool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *left,
2104224145Sdim                                      const ObjCMethodDecl *right,
2105224145Sdim                                      MethodMatchStrategy strategy) {
2106224145Sdim  if (!matchTypes(Context, strategy,
2107224145Sdim                  left->getResultType(), right->getResultType()))
2108224145Sdim    return false;
2109198092Srdivacky
2110249423Sdim  // If either is hidden, it is not considered to match.
2111249423Sdim  if (left->isHidden() || right->isHidden())
2112249423Sdim    return false;
2113249423Sdim
2114234353Sdim  if (getLangOpts().ObjCAutoRefCount &&
2115224145Sdim      (left->hasAttr<NSReturnsRetainedAttr>()
2116224145Sdim         != right->hasAttr<NSReturnsRetainedAttr>() ||
2117224145Sdim       left->hasAttr<NSConsumesSelfAttr>()
2118224145Sdim         != right->hasAttr<NSConsumesSelfAttr>()))
2119224145Sdim    return false;
2120224145Sdim
2121226633Sdim  ObjCMethodDecl::param_const_iterator
2122239462Sdim    li = left->param_begin(), le = left->param_end(), ri = right->param_begin(),
2123239462Sdim    re = right->param_end();
2124224145Sdim
2125239462Sdim  for (; li != le && ri != re; ++li, ++ri) {
2126224145Sdim    assert(ri != right->param_end() && "Param mismatch");
2127226633Sdim    const ParmVarDecl *lparm = *li, *rparm = *ri;
2128224145Sdim
2129224145Sdim    if (!matchTypes(Context, strategy, lparm->getType(), rparm->getType()))
2130193326Sed      return false;
2131224145Sdim
2132234353Sdim    if (getLangOpts().ObjCAutoRefCount &&
2133224145Sdim        lparm->hasAttr<NSConsumedAttr>() != rparm->hasAttr<NSConsumedAttr>())
2134193326Sed      return false;
2135193326Sed  }
2136193326Sed  return true;
2137193326Sed}
2138193326Sed
2139234353Sdimvoid Sema::addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method) {
2140251662Sdim  // Record at the head of the list whether there were 0, 1, or >= 2 methods
2141251662Sdim  // inside categories.
2142251662Sdim  if (ObjCCategoryDecl *
2143251662Sdim        CD = dyn_cast<ObjCCategoryDecl>(Method->getDeclContext()))
2144251662Sdim    if (!CD->IsClassExtension() && List->getBits() < 2)
2145251662Sdim        List->setBits(List->getBits()+1);
2146251662Sdim
2147234353Sdim  // If the list is empty, make it a singleton list.
2148234353Sdim  if (List->Method == 0) {
2149234353Sdim    List->Method = Method;
2150251662Sdim    List->setNext(0);
2151193326Sed    return;
2152193326Sed  }
2153234353Sdim
2154193326Sed  // We've seen a method with this name, see if we have already seen this type
2155193326Sed  // signature.
2156234353Sdim  ObjCMethodList *Previous = List;
2157251662Sdim  for (; List; Previous = List, List = List->getNext()) {
2158263508Sdim    // If we are building a module, keep all of the methods.
2159263508Sdim    if (getLangOpts().Modules && !getLangOpts().CurrentModule.empty())
2160263508Sdim      continue;
2161263508Sdim
2162234353Sdim    if (!MatchTwoMethodDeclarations(Method, List->Method))
2163234353Sdim      continue;
2164234353Sdim
2165234353Sdim    ObjCMethodDecl *PrevObjCMethod = List->Method;
2166224145Sdim
2167234353Sdim    // Propagate the 'defined' bit.
2168234353Sdim    if (Method->isDefined())
2169234353Sdim      PrevObjCMethod->setDefined(true);
2170234353Sdim
2171234353Sdim    // If a method is deprecated, push it in the global pool.
2172234353Sdim    // This is used for better diagnostics.
2173234353Sdim    if (Method->isDeprecated()) {
2174234353Sdim      if (!PrevObjCMethod->isDeprecated())
2175234353Sdim        List->Method = Method;
2176212904Sdim    }
2177234353Sdim    // If new method is unavailable, push it into global pool
2178234353Sdim    // unless previous one is deprecated.
2179234353Sdim    if (Method->isUnavailable()) {
2180234353Sdim      if (PrevObjCMethod->getAvailability() < AR_Deprecated)
2181234353Sdim        List->Method = Method;
2182234353Sdim    }
2183234353Sdim
2184234353Sdim    return;
2185224145Sdim  }
2186234353Sdim
2187193326Sed  // We have a new signature for an existing method - add it.
2188193326Sed  // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
2189203955Srdivacky  ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>();
2190251662Sdim  Previous->setNext(new (Mem) ObjCMethodList(Method, 0));
2191193326Sed}
2192193326Sed
2193234353Sdim/// \brief Read the contents of the method pool for a given selector from
2194234353Sdim/// external storage.
2195234353Sdimvoid Sema::ReadMethodPool(Selector Sel) {
2196234353Sdim  assert(ExternalSource && "We need an external AST source");
2197234353Sdim  ExternalSource->ReadMethodPool(Sel);
2198234353Sdim}
2199234353Sdim
2200234353Sdimvoid Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl,
2201234353Sdim                                 bool instance) {
2202234353Sdim  // Ignore methods of invalid containers.
2203234353Sdim  if (cast<Decl>(Method->getDeclContext())->isInvalidDecl())
2204234353Sdim    return;
2205234353Sdim
2206234353Sdim  if (ExternalSource)
2207234353Sdim    ReadMethodPool(Method->getSelector());
2208234353Sdim
2209234353Sdim  GlobalMethodPool::iterator Pos = MethodPool.find(Method->getSelector());
2210234353Sdim  if (Pos == MethodPool.end())
2211234353Sdim    Pos = MethodPool.insert(std::make_pair(Method->getSelector(),
2212234353Sdim                                           GlobalMethods())).first;
2213234353Sdim
2214234353Sdim  Method->setDefined(impl);
2215234353Sdim
2216234353Sdim  ObjCMethodList &Entry = instance ? Pos->second.first : Pos->second.second;
2217234353Sdim  addMethodToGlobalList(&Entry, Method);
2218234353Sdim}
2219234353Sdim
2220224145Sdim/// Determines if this is an "acceptable" loose mismatch in the global
2221224145Sdim/// method pool.  This exists mostly as a hack to get around certain
2222224145Sdim/// global mismatches which we can't afford to make warnings / errors.
2223224145Sdim/// Really, what we want is a way to take a method out of the global
2224224145Sdim/// method pool.
2225224145Sdimstatic bool isAcceptableMethodMismatch(ObjCMethodDecl *chosen,
2226224145Sdim                                       ObjCMethodDecl *other) {
2227224145Sdim  if (!chosen->isInstanceMethod())
2228224145Sdim    return false;
2229224145Sdim
2230224145Sdim  Selector sel = chosen->getSelector();
2231224145Sdim  if (!sel.isUnarySelector() || sel.getNameForSlot(0) != "length")
2232224145Sdim    return false;
2233224145Sdim
2234224145Sdim  // Don't complain about mismatches for -length if the method we
2235224145Sdim  // chose has an integral result type.
2236224145Sdim  return (chosen->getResultType()->isIntegerType());
2237224145Sdim}
2238224145Sdim
2239212904SdimObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R,
2240212904Sdim                                               bool receiverIdOrClass,
2241212904Sdim                                               bool warn, bool instance) {
2242234353Sdim  if (ExternalSource)
2243234353Sdim    ReadMethodPool(Sel);
2244234353Sdim
2245212904Sdim  GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
2246234353Sdim  if (Pos == MethodPool.end())
2247234353Sdim    return 0;
2248193326Sed
2249249423Sdim  // Gather the non-hidden methods.
2250212904Sdim  ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second;
2251263508Sdim  SmallVector<ObjCMethodDecl *, 4> Methods;
2252251662Sdim  for (ObjCMethodList *M = &MethList; M; M = M->getNext()) {
2253249423Sdim    if (M->Method && !M->Method->isHidden()) {
2254249423Sdim      // If we're not supposed to warn about mismatches, we're done.
2255249423Sdim      if (!warn)
2256249423Sdim        return M->Method;
2257198092Srdivacky
2258249423Sdim      Methods.push_back(M->Method);
2259249423Sdim    }
2260249423Sdim  }
2261224145Sdim
2262249423Sdim  // If there aren't any visible methods, we're done.
2263249423Sdim  // FIXME: Recover if there are any known-but-hidden methods?
2264249423Sdim  if (Methods.empty())
2265249423Sdim    return 0;
2266249423Sdim
2267249423Sdim  if (Methods.size() == 1)
2268249423Sdim    return Methods[0];
2269249423Sdim
2270249423Sdim  // We found multiple methods, so we may have to complain.
2271249423Sdim  bool issueDiagnostic = false, issueError = false;
2272249423Sdim
2273249423Sdim  // We support a warning which complains about *any* difference in
2274249423Sdim  // method signature.
2275249423Sdim  bool strictSelectorMatch =
2276249423Sdim    (receiverIdOrClass && warn &&
2277249423Sdim     (Diags.getDiagnosticLevel(diag::warn_strict_multiple_method_decl,
2278249423Sdim                               R.getBegin())
2279249423Sdim        != DiagnosticsEngine::Ignored));
2280249423Sdim  if (strictSelectorMatch) {
2281249423Sdim    for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
2282249423Sdim      if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_strict)) {
2283249423Sdim        issueDiagnostic = true;
2284249423Sdim        break;
2285212904Sdim      }
2286249423Sdim    }
2287249423Sdim  }
2288193326Sed
2289249423Sdim  // If we didn't see any strict differences, we won't see any loose
2290249423Sdim  // differences.  In ARC, however, we also need to check for loose
2291249423Sdim  // mismatches, because most of them are errors.
2292249423Sdim  if (!strictSelectorMatch ||
2293249423Sdim      (issueDiagnostic && getLangOpts().ObjCAutoRefCount))
2294249423Sdim    for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
2295249423Sdim      // This checks if the methods differ in type mismatch.
2296249423Sdim      if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_loose) &&
2297249423Sdim          !isAcceptableMethodMismatch(Methods[0], Methods[I])) {
2298249423Sdim        issueDiagnostic = true;
2299249423Sdim        if (getLangOpts().ObjCAutoRefCount)
2300249423Sdim          issueError = true;
2301249423Sdim        break;
2302212904Sdim      }
2303249423Sdim    }
2304193326Sed
2305249423Sdim  if (issueDiagnostic) {
2306249423Sdim    if (issueError)
2307249423Sdim      Diag(R.getBegin(), diag::err_arc_multiple_method_decl) << Sel << R;
2308249423Sdim    else if (strictSelectorMatch)
2309249423Sdim      Diag(R.getBegin(), diag::warn_strict_multiple_method_decl) << Sel << R;
2310249423Sdim    else
2311249423Sdim      Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
2312224145Sdim
2313249423Sdim    Diag(Methods[0]->getLocStart(),
2314249423Sdim         issueError ? diag::note_possibility : diag::note_using)
2315249423Sdim      << Methods[0]->getSourceRange();
2316249423Sdim    for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
2317249423Sdim      Diag(Methods[I]->getLocStart(), diag::note_also_found)
2318249423Sdim        << Methods[I]->getSourceRange();
2319193326Sed  }
2320249423Sdim  }
2321249423Sdim  return Methods[0];
2322193326Sed}
2323193326Sed
2324212904SdimObjCMethodDecl *Sema::LookupImplementedMethodInGlobalPool(Selector Sel) {
2325212904Sdim  GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
2326212904Sdim  if (Pos == MethodPool.end())
2327212904Sdim    return 0;
2328193326Sed
2329212904Sdim  GlobalMethods &Methods = Pos->second;
2330198092Srdivacky
2331212904Sdim  if (Methods.first.Method && Methods.first.Method->isDefined())
2332212904Sdim    return Methods.first.Method;
2333212904Sdim  if (Methods.second.Method && Methods.second.Method->isDefined())
2334212904Sdim    return Methods.second.Method;
2335212904Sdim  return 0;
2336193326Sed}
2337193326Sed
2338263508Sdimstatic void
2339263508SdimHelperSelectorsForTypoCorrection(
2340263508Sdim                      SmallVectorImpl<const ObjCMethodDecl *> &BestMethod,
2341263508Sdim                      StringRef Typo, const ObjCMethodDecl * Method) {
2342263508Sdim  const unsigned MaxEditDistance = 1;
2343263508Sdim  unsigned BestEditDistance = MaxEditDistance + 1;
2344263508Sdim  std::string MethodName = Method->getSelector().getAsString();
2345263508Sdim
2346263508Sdim  unsigned MinPossibleEditDistance = abs((int)MethodName.size() - (int)Typo.size());
2347263508Sdim  if (MinPossibleEditDistance > 0 &&
2348263508Sdim      Typo.size() / MinPossibleEditDistance < 1)
2349263508Sdim    return;
2350263508Sdim  unsigned EditDistance = Typo.edit_distance(MethodName, true, MaxEditDistance);
2351263508Sdim  if (EditDistance > MaxEditDistance)
2352263508Sdim    return;
2353263508Sdim  if (EditDistance == BestEditDistance)
2354263508Sdim    BestMethod.push_back(Method);
2355263508Sdim  else if (EditDistance < BestEditDistance) {
2356263508Sdim    BestMethod.clear();
2357263508Sdim    BestMethod.push_back(Method);
2358263508Sdim  }
2359263508Sdim}
2360263508Sdim
2361263508Sdimstatic bool HelperIsMethodInObjCType(Sema &S, Selector Sel,
2362263508Sdim                                     QualType ObjectType) {
2363263508Sdim  if (ObjectType.isNull())
2364263508Sdim    return true;
2365263508Sdim  if (S.LookupMethodInObjectType(Sel, ObjectType, true/*Instance method*/))
2366263508Sdim    return true;
2367263508Sdim  return S.LookupMethodInObjectType(Sel, ObjectType, false/*Class method*/) != 0;
2368263508Sdim}
2369263508Sdim
2370263508Sdimconst ObjCMethodDecl *
2371263508SdimSema::SelectorsForTypoCorrection(Selector Sel,
2372263508Sdim                                 QualType ObjectType) {
2373263508Sdim  unsigned NumArgs = Sel.getNumArgs();
2374263508Sdim  SmallVector<const ObjCMethodDecl *, 8> Methods;
2375263508Sdim  bool ObjectIsId = true, ObjectIsClass = true;
2376263508Sdim  if (ObjectType.isNull())
2377263508Sdim    ObjectIsId = ObjectIsClass = false;
2378263508Sdim  else if (!ObjectType->isObjCObjectPointerType())
2379263508Sdim    return 0;
2380263508Sdim  else if (const ObjCObjectPointerType *ObjCPtr =
2381263508Sdim           ObjectType->getAsObjCInterfacePointerType()) {
2382263508Sdim    ObjectType = QualType(ObjCPtr->getInterfaceType(), 0);
2383263508Sdim    ObjectIsId = ObjectIsClass = false;
2384263508Sdim  }
2385263508Sdim  else if (ObjectType->isObjCIdType() || ObjectType->isObjCQualifiedIdType())
2386263508Sdim    ObjectIsClass = false;
2387263508Sdim  else if (ObjectType->isObjCClassType() || ObjectType->isObjCQualifiedClassType())
2388263508Sdim    ObjectIsId = false;
2389263508Sdim  else
2390263508Sdim    return 0;
2391263508Sdim
2392263508Sdim  for (GlobalMethodPool::iterator b = MethodPool.begin(),
2393263508Sdim       e = MethodPool.end(); b != e; b++) {
2394263508Sdim    // instance methods
2395263508Sdim    for (ObjCMethodList *M = &b->second.first; M; M=M->getNext())
2396263508Sdim      if (M->Method &&
2397263508Sdim          (M->Method->getSelector().getNumArgs() == NumArgs) &&
2398263508Sdim          (M->Method->getSelector() != Sel)) {
2399263508Sdim        if (ObjectIsId)
2400263508Sdim          Methods.push_back(M->Method);
2401263508Sdim        else if (!ObjectIsClass &&
2402263508Sdim                 HelperIsMethodInObjCType(*this, M->Method->getSelector(), ObjectType))
2403263508Sdim          Methods.push_back(M->Method);
2404263508Sdim      }
2405263508Sdim    // class methods
2406263508Sdim    for (ObjCMethodList *M = &b->second.second; M; M=M->getNext())
2407263508Sdim      if (M->Method &&
2408263508Sdim          (M->Method->getSelector().getNumArgs() == NumArgs) &&
2409263508Sdim          (M->Method->getSelector() != Sel)) {
2410263508Sdim        if (ObjectIsClass)
2411263508Sdim          Methods.push_back(M->Method);
2412263508Sdim        else if (!ObjectIsId &&
2413263508Sdim                 HelperIsMethodInObjCType(*this, M->Method->getSelector(), ObjectType))
2414263508Sdim          Methods.push_back(M->Method);
2415263508Sdim      }
2416263508Sdim  }
2417263508Sdim
2418263508Sdim  SmallVector<const ObjCMethodDecl *, 8> SelectedMethods;
2419263508Sdim  for (unsigned i = 0, e = Methods.size(); i < e; i++) {
2420263508Sdim    HelperSelectorsForTypoCorrection(SelectedMethods,
2421263508Sdim                                     Sel.getAsString(), Methods[i]);
2422263508Sdim  }
2423263508Sdim  return (SelectedMethods.size() == 1) ? SelectedMethods[0] : NULL;
2424263508Sdim}
2425263508Sdim
2426263508Sdimstatic void
2427263508SdimHelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S,
2428263508Sdim                                              ObjCMethodList &MethList) {
2429263508Sdim  ObjCMethodList *M = &MethList;
2430263508Sdim  ObjCMethodDecl *TargetMethod = M->Method;
2431263508Sdim  while (TargetMethod &&
2432263508Sdim         isa<ObjCImplDecl>(TargetMethod->getDeclContext())) {
2433263508Sdim    M = M->getNext();
2434263508Sdim    TargetMethod = M ? M->Method : 0;
2435263508Sdim  }
2436263508Sdim  if (!TargetMethod)
2437263508Sdim    return;
2438263508Sdim  bool FirstTime = true;
2439263508Sdim  for (M = M->getNext(); M; M=M->getNext()) {
2440263508Sdim    ObjCMethodDecl *MatchingMethodDecl = M->Method;
2441263508Sdim    if (isa<ObjCImplDecl>(MatchingMethodDecl->getDeclContext()))
2442263508Sdim      continue;
2443263508Sdim    if (!S.MatchTwoMethodDeclarations(TargetMethod,
2444263508Sdim                                      MatchingMethodDecl, Sema::MMS_loose)) {
2445263508Sdim      if (FirstTime) {
2446263508Sdim        FirstTime = false;
2447263508Sdim        S.Diag(TargetMethod->getLocation(), diag::warning_multiple_selectors)
2448263508Sdim        << TargetMethod->getSelector();
2449263508Sdim      }
2450263508Sdim      S.Diag(MatchingMethodDecl->getLocation(), diag::note_also_found);
2451263508Sdim    }
2452263508Sdim  }
2453263508Sdim}
2454263508Sdim
2455263508Sdimvoid Sema::DiagnoseMismatchedMethodsInGlobalPool() {
2456263508Sdim  unsigned DIAG = diag::warning_multiple_selectors;
2457263508Sdim  if (Diags.getDiagnosticLevel(DIAG, SourceLocation())
2458263508Sdim      == DiagnosticsEngine::Ignored)
2459263508Sdim    return;
2460263508Sdim  for (GlobalMethodPool::iterator b = MethodPool.begin(),
2461263508Sdim       e = MethodPool.end(); b != e; b++) {
2462263508Sdim    // first, instance methods
2463263508Sdim    ObjCMethodList &InstMethList = b->second.first;
2464263508Sdim    HelperToDiagnoseMismatchedMethodsInGlobalPool(*this, InstMethList);
2465263508Sdim    // second, class methods
2466263508Sdim    ObjCMethodList &ClsMethList = b->second.second;
2467263508Sdim    HelperToDiagnoseMismatchedMethodsInGlobalPool(*this, ClsMethList);
2468263508Sdim  }
2469263508Sdim}
2470263508Sdim
2471263508Sdim/// DiagnoseDuplicateIvars -
2472204643Srdivacky/// Check for duplicate ivars in the entire class at the start of
2473239462Sdim/// \@implementation. This becomes necesssary because class extension can
2474204643Srdivacky/// add ivars to a class in random order which will not be known until
2475239462Sdim/// class's \@implementation is seen.
2476204643Srdivackyvoid Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID,
2477204643Srdivacky                                  ObjCInterfaceDecl *SID) {
2478204643Srdivacky  for (ObjCInterfaceDecl::ivar_iterator IVI = ID->ivar_begin(),
2479204643Srdivacky       IVE = ID->ivar_end(); IVI != IVE; ++IVI) {
2480239462Sdim    ObjCIvarDecl* Ivar = *IVI;
2481204643Srdivacky    if (Ivar->isInvalidDecl())
2482204643Srdivacky      continue;
2483204643Srdivacky    if (IdentifierInfo *II = Ivar->getIdentifier()) {
2484204643Srdivacky      ObjCIvarDecl* prevIvar = SID->lookupInstanceVariable(II);
2485204643Srdivacky      if (prevIvar) {
2486204643Srdivacky        Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;
2487204643Srdivacky        Diag(prevIvar->getLocation(), diag::note_previous_declaration);
2488204643Srdivacky        Ivar->setInvalidDecl();
2489204643Srdivacky      }
2490204643Srdivacky    }
2491204643Srdivacky  }
2492204643Srdivacky}
2493204643Srdivacky
2494234353SdimSema::ObjCContainerKind Sema::getObjCContainerKind() const {
2495234353Sdim  switch (CurContext->getDeclKind()) {
2496234353Sdim    case Decl::ObjCInterface:
2497234353Sdim      return Sema::OCK_Interface;
2498234353Sdim    case Decl::ObjCProtocol:
2499234353Sdim      return Sema::OCK_Protocol;
2500234353Sdim    case Decl::ObjCCategory:
2501234353Sdim      if (dyn_cast<ObjCCategoryDecl>(CurContext)->IsClassExtension())
2502234353Sdim        return Sema::OCK_ClassExtension;
2503234353Sdim      else
2504234353Sdim        return Sema::OCK_Category;
2505234353Sdim    case Decl::ObjCImplementation:
2506234353Sdim      return Sema::OCK_Implementation;
2507234353Sdim    case Decl::ObjCCategoryImpl:
2508234353Sdim      return Sema::OCK_CategoryImplementation;
2509234353Sdim
2510234353Sdim    default:
2511234353Sdim      return Sema::OCK_None;
2512234353Sdim  }
2513234353Sdim}
2514234353Sdim
2515263508Sdim// Note: For class/category implementations, allMethods is always null.
2516263508SdimDecl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods,
2517263508Sdim                       ArrayRef<DeclGroupPtrTy> allTUVars) {
2518234353Sdim  if (getObjCContainerKind() == Sema::OCK_None)
2519234353Sdim    return 0;
2520234353Sdim
2521234353Sdim  assert(AtEnd.isValid() && "Invalid location for '@end'");
2522234353Sdim
2523226633Sdim  ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
2524226633Sdim  Decl *ClassDecl = cast<Decl>(OCD);
2525199482Srdivacky
2526198092Srdivacky  bool isInterfaceDeclKind =
2527193326Sed        isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl)
2528193326Sed         || isa<ObjCProtocolDecl>(ClassDecl);
2529193326Sed  bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl);
2530193326Sed
2531193326Sed  // FIXME: Remove these and use the ObjCContainerDecl/DeclContext.
2532193326Sed  llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;
2533193326Sed  llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;
2534193326Sed
2535263508Sdim  for (unsigned i = 0, e = allMethods.size(); i != e; i++ ) {
2536193326Sed    ObjCMethodDecl *Method =
2537212904Sdim      cast_or_null<ObjCMethodDecl>(allMethods[i]);
2538193326Sed
2539193326Sed    if (!Method) continue;  // Already issued a diagnostic.
2540193326Sed    if (Method->isInstanceMethod()) {
2541193326Sed      /// Check for instance method of the same name with incompatible types
2542193326Sed      const ObjCMethodDecl *&PrevMethod = InsMap[Method->getSelector()];
2543198092Srdivacky      bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
2544193326Sed                              : false;
2545198092Srdivacky      if ((isInterfaceDeclKind && PrevMethod && !match)
2546193326Sed          || (checkIdenticalMethods && match)) {
2547193326Sed          Diag(Method->getLocation(), diag::err_duplicate_method_decl)
2548193326Sed            << Method->getDeclName();
2549193326Sed          Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
2550218893Sdim        Method->setInvalidDecl();
2551193326Sed      } else {
2552234353Sdim        if (PrevMethod) {
2553226633Sdim          Method->setAsRedeclaration(PrevMethod);
2554234353Sdim          if (!Context.getSourceManager().isInSystemHeader(
2555234353Sdim                 Method->getLocation()))
2556234353Sdim            Diag(Method->getLocation(), diag::warn_duplicate_method_decl)
2557234353Sdim              << Method->getDeclName();
2558234353Sdim          Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
2559234353Sdim        }
2560193326Sed        InsMap[Method->getSelector()] = Method;
2561193326Sed        /// The following allows us to typecheck messages to "id".
2562193326Sed        AddInstanceMethodToGlobalPool(Method);
2563193326Sed      }
2564198092Srdivacky    } else {
2565193326Sed      /// Check for class method of the same name with incompatible types
2566193326Sed      const ObjCMethodDecl *&PrevMethod = ClsMap[Method->getSelector()];
2567198092Srdivacky      bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
2568193326Sed                              : false;
2569198092Srdivacky      if ((isInterfaceDeclKind && PrevMethod && !match)
2570193326Sed          || (checkIdenticalMethods && match)) {
2571193326Sed        Diag(Method->getLocation(), diag::err_duplicate_method_decl)
2572193326Sed          << Method->getDeclName();
2573193326Sed        Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
2574218893Sdim        Method->setInvalidDecl();
2575193326Sed      } else {
2576234353Sdim        if (PrevMethod) {
2577226633Sdim          Method->setAsRedeclaration(PrevMethod);
2578234353Sdim          if (!Context.getSourceManager().isInSystemHeader(
2579234353Sdim                 Method->getLocation()))
2580234353Sdim            Diag(Method->getLocation(), diag::warn_duplicate_method_decl)
2581234353Sdim              << Method->getDeclName();
2582234353Sdim          Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
2583234353Sdim        }
2584193326Sed        ClsMap[Method->getSelector()] = Method;
2585193326Sed        AddFactoryMethodToGlobalPool(Method);
2586193326Sed      }
2587193326Sed    }
2588193326Sed  }
2589249423Sdim  if (isa<ObjCInterfaceDecl>(ClassDecl)) {
2590249423Sdim    // Nothing to do here.
2591193326Sed  } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
2592193326Sed    // Categories are used to extend the class by declaring new methods.
2593198092Srdivacky    // By the same token, they are also used to add new properties. No
2594193326Sed    // need to compare the added property to those in the class.
2595193326Sed
2596218893Sdim    if (C->IsClassExtension()) {
2597218893Sdim      ObjCInterfaceDecl *CCPrimary = C->getClassInterface();
2598218893Sdim      DiagnoseClassExtensionDupMethods(C, CCPrimary);
2599218893Sdim    }
2600193326Sed  }
2601193326Sed  if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(ClassDecl)) {
2602203955Srdivacky    if (CDecl->getIdentifier())
2603203955Srdivacky      // ProcessPropertyDecl is responsible for diagnosing conflicts with any
2604203955Srdivacky      // user-defined setter/getter. It also synthesizes setter/getter methods
2605203955Srdivacky      // and adds them to the DeclContext and global method pools.
2606203955Srdivacky      for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(),
2607203955Srdivacky                                            E = CDecl->prop_end();
2608203955Srdivacky           I != E; ++I)
2609203955Srdivacky        ProcessPropertyDecl(*I, CDecl);
2610202379Srdivacky    CDecl->setAtEndRange(AtEnd);
2611193326Sed  }
2612193326Sed  if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
2613202379Srdivacky    IC->setAtEndRange(AtEnd);
2614199482Srdivacky    if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) {
2615218893Sdim      // Any property declared in a class extension might have user
2616218893Sdim      // declared setter or getter in current class extension or one
2617218893Sdim      // of the other class extensions. Mark them as synthesized as
2618218893Sdim      // property will be synthesized when property with same name is
2619218893Sdim      // seen in the @implementation.
2620249423Sdim      for (ObjCInterfaceDecl::visible_extensions_iterator
2621249423Sdim             Ext = IDecl->visible_extensions_begin(),
2622249423Sdim             ExtEnd = IDecl->visible_extensions_end();
2623249423Sdim           Ext != ExtEnd; ++Ext) {
2624249423Sdim        for (ObjCContainerDecl::prop_iterator I = Ext->prop_begin(),
2625249423Sdim             E = Ext->prop_end(); I != E; ++I) {
2626239462Sdim          ObjCPropertyDecl *Property = *I;
2627218893Sdim          // Skip over properties declared @dynamic
2628218893Sdim          if (const ObjCPropertyImplDecl *PIDecl
2629218893Sdim              = IC->FindPropertyImplDecl(Property->getIdentifier()))
2630218893Sdim            if (PIDecl->getPropertyImplementation()
2631218893Sdim                  == ObjCPropertyImplDecl::Dynamic)
2632218893Sdim              continue;
2633249423Sdim
2634249423Sdim          for (ObjCInterfaceDecl::visible_extensions_iterator
2635249423Sdim                 Ext = IDecl->visible_extensions_begin(),
2636249423Sdim                 ExtEnd = IDecl->visible_extensions_end();
2637249423Sdim               Ext != ExtEnd; ++Ext) {
2638249423Sdim            if (ObjCMethodDecl *GetterMethod
2639249423Sdim                  = Ext->getInstanceMethod(Property->getGetterName()))
2640243830Sdim              GetterMethod->setPropertyAccessor(true);
2641218893Sdim            if (!Property->isReadOnly())
2642249423Sdim              if (ObjCMethodDecl *SetterMethod
2643249423Sdim                    = Ext->getInstanceMethod(Property->getSetterName()))
2644243830Sdim                SetterMethod->setPropertyAccessor(true);
2645249423Sdim          }
2646218893Sdim        }
2647218893Sdim      }
2648208600Srdivacky      ImplMethodsVsClassMethods(S, IC, IDecl);
2649199482Srdivacky      AtomicPropertySetterGetterRules(IC, IDecl);
2650224145Sdim      DiagnoseOwningPropertyGetterSynthesis(IC);
2651212904Sdim
2652234353Sdim      bool HasRootClassAttr = IDecl->hasAttr<ObjCRootClassAttr>();
2653234353Sdim      if (IDecl->getSuperClass() == NULL) {
2654234353Sdim        // This class has no superclass, so check that it has been marked with
2655234353Sdim        // __attribute((objc_root_class)).
2656234353Sdim        if (!HasRootClassAttr) {
2657234353Sdim          SourceLocation DeclLoc(IDecl->getLocation());
2658234353Sdim          SourceLocation SuperClassLoc(PP.getLocForEndOfToken(DeclLoc));
2659234353Sdim          Diag(DeclLoc, diag::warn_objc_root_class_missing)
2660234353Sdim            << IDecl->getIdentifier();
2661234353Sdim          // See if NSObject is in the current scope, and if it is, suggest
2662234353Sdim          // adding " : NSObject " to the class declaration.
2663234353Sdim          NamedDecl *IF = LookupSingleName(TUScope,
2664234353Sdim                                           NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject),
2665234353Sdim                                           DeclLoc, LookupOrdinaryName);
2666234353Sdim          ObjCInterfaceDecl *NSObjectDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
2667234353Sdim          if (NSObjectDecl && NSObjectDecl->getDefinition()) {
2668234353Sdim            Diag(SuperClassLoc, diag::note_objc_needs_superclass)
2669234353Sdim              << FixItHint::CreateInsertion(SuperClassLoc, " : NSObject ");
2670234353Sdim          } else {
2671234353Sdim            Diag(SuperClassLoc, diag::note_objc_needs_superclass);
2672234353Sdim          }
2673234353Sdim        }
2674234353Sdim      } else if (HasRootClassAttr) {
2675234353Sdim        // Complain that only root classes may have this attribute.
2676234353Sdim        Diag(IDecl->getLocation(), diag::err_objc_root_class_subclass);
2677234353Sdim      }
2678234353Sdim
2679239462Sdim      if (LangOpts.ObjCRuntime.isNonFragile()) {
2680204643Srdivacky        while (IDecl->getSuperClass()) {
2681204643Srdivacky          DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass());
2682204643Srdivacky          IDecl = IDecl->getSuperClass();
2683204643Srdivacky        }
2684234353Sdim      }
2685199482Srdivacky    }
2686207619Srdivacky    SetIvarInitializers(IC);
2687198092Srdivacky  } else if (ObjCCategoryImplDecl* CatImplClass =
2688193326Sed                                   dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
2689202379Srdivacky    CatImplClass->setAtEndRange(AtEnd);
2690198092Srdivacky
2691193326Sed    // Find category interface decl and then check that all methods declared
2692193326Sed    // in this interface are implemented in the category @implementation.
2693193326Sed    if (ObjCInterfaceDecl* IDecl = CatImplClass->getClassInterface()) {
2694249423Sdim      if (ObjCCategoryDecl *Cat
2695249423Sdim            = IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier())) {
2696249423Sdim        ImplMethodsVsClassMethods(S, CatImplClass, Cat);
2697193326Sed      }
2698193326Sed    }
2699193326Sed  }
2700193326Sed  if (isInterfaceDeclKind) {
2701193326Sed    // Reject invalid vardecls.
2702263508Sdim    for (unsigned i = 0, e = allTUVars.size(); i != e; i++) {
2703263508Sdim      DeclGroupRef DG = allTUVars[i].get();
2704193326Sed      for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
2705193326Sed        if (VarDecl *VDecl = dyn_cast<VarDecl>(*I)) {
2706193326Sed          if (!VDecl->hasExternalStorage())
2707193326Sed            Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass);
2708193326Sed        }
2709193326Sed    }
2710193326Sed  }
2711226633Sdim  ActOnObjCContainerFinishDefinition();
2712234353Sdim
2713263508Sdim  for (unsigned i = 0, e = allTUVars.size(); i != e; i++) {
2714263508Sdim    DeclGroupRef DG = allTUVars[i].get();
2715234353Sdim    for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
2716234353Sdim      (*I)->setTopLevelDeclInObjCContainer();
2717234353Sdim    Consumer.HandleTopLevelDeclInObjCContainer(DG);
2718234353Sdim  }
2719234353Sdim
2720239462Sdim  ActOnDocumentableDecl(ClassDecl);
2721234353Sdim  return ClassDecl;
2722193326Sed}
2723193326Sed
2724193326Sed
2725193326Sed/// CvtQTToAstBitMask - utility routine to produce an AST bitmask for
2726193326Sed/// objective-c's type qualifier from the parser version of the same info.
2727198092Srdivackystatic Decl::ObjCDeclQualifier
2728193326SedCvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) {
2729221345Sdim  return (Decl::ObjCDeclQualifier) (unsigned) PQTVal;
2730193326Sed}
2731193326Sed
2732207619Srdivackystatic inline
2733243830Sdimunsigned countAlignAttr(const AttrVec &A) {
2734243830Sdim  unsigned count=0;
2735243830Sdim  for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i)
2736243830Sdim    if ((*i)->getKind() == attr::Aligned)
2737243830Sdim      ++count;
2738243830Sdim  return count;
2739243830Sdim}
2740243830Sdim
2741243830Sdimstatic inline
2742234353Sdimbool containsInvalidMethodImplAttribute(ObjCMethodDecl *IMD,
2743234353Sdim                                        const AttrVec &A) {
2744234353Sdim  // If method is only declared in implementation (private method),
2745234353Sdim  // No need to issue any diagnostics on method definition with attributes.
2746234353Sdim  if (!IMD)
2747234353Sdim    return false;
2748243830Sdim
2749234353Sdim  // method declared in interface has no attribute.
2750243830Sdim  // But implementation has attributes. This is invalid.
2751243830Sdim  // Except when implementation has 'Align' attribute which is
2752243830Sdim  // immaterial to method declared in interface.
2753234353Sdim  if (!IMD->hasAttrs())
2754243830Sdim    return (A.size() > countAlignAttr(A));
2755234353Sdim
2756234353Sdim  const AttrVec &D = IMD->getAttrs();
2757243830Sdim
2758243830Sdim  unsigned countAlignOnImpl = countAlignAttr(A);
2759243830Sdim  if (!countAlignOnImpl && (A.size() != D.size()))
2760234353Sdim    return true;
2761243830Sdim  else if (countAlignOnImpl) {
2762243830Sdim    unsigned countAlignOnDecl = countAlignAttr(D);
2763243830Sdim    if (countAlignOnDecl && (A.size() != D.size()))
2764243830Sdim      return true;
2765243830Sdim    else if (!countAlignOnDecl &&
2766243830Sdim             ((A.size()-countAlignOnImpl) != D.size()))
2767243830Sdim      return true;
2768243830Sdim  }
2769243830Sdim
2770234353Sdim  // attributes on method declaration and definition must match exactly.
2771234353Sdim  // Note that we have at most a couple of attributes on methods, so this
2772234353Sdim  // n*n search is good enough.
2773234353Sdim  for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i) {
2774243830Sdim    if ((*i)->getKind() == attr::Aligned)
2775243830Sdim      continue;
2776234353Sdim    bool match = false;
2777234353Sdim    for (AttrVec::const_iterator i1 = D.begin(), e1 = D.end(); i1 != e1; ++i1) {
2778234353Sdim      if ((*i)->getKind() == (*i1)->getKind()) {
2779234353Sdim        match = true;
2780234353Sdim        break;
2781234353Sdim      }
2782234353Sdim    }
2783234353Sdim    if (!match)
2784212904Sdim      return true;
2785234353Sdim  }
2786243830Sdim
2787212904Sdim  return false;
2788207619Srdivacky}
2789207619Srdivacky
2790223017Sdim/// \brief Check whether the declared result type of the given Objective-C
2791223017Sdim/// method declaration is compatible with the method's class.
2792223017Sdim///
2793239462Sdimstatic Sema::ResultTypeCompatibilityKind
2794223017SdimCheckRelatedResultTypeCompatibility(Sema &S, ObjCMethodDecl *Method,
2795223017Sdim                                    ObjCInterfaceDecl *CurrentClass) {
2796223017Sdim  QualType ResultType = Method->getResultType();
2797223017Sdim
2798223017Sdim  // If an Objective-C method inherits its related result type, then its
2799223017Sdim  // declared result type must be compatible with its own class type. The
2800223017Sdim  // declared result type is compatible if:
2801223017Sdim  if (const ObjCObjectPointerType *ResultObjectType
2802223017Sdim                                = ResultType->getAs<ObjCObjectPointerType>()) {
2803223017Sdim    //   - it is id or qualified id, or
2804223017Sdim    if (ResultObjectType->isObjCIdType() ||
2805223017Sdim        ResultObjectType->isObjCQualifiedIdType())
2806239462Sdim      return Sema::RTC_Compatible;
2807223017Sdim
2808223017Sdim    if (CurrentClass) {
2809223017Sdim      if (ObjCInterfaceDecl *ResultClass
2810223017Sdim                                      = ResultObjectType->getInterfaceDecl()) {
2811223017Sdim        //   - it is the same as the method's class type, or
2812234353Sdim        if (declaresSameEntity(CurrentClass, ResultClass))
2813239462Sdim          return Sema::RTC_Compatible;
2814223017Sdim
2815223017Sdim        //   - it is a superclass of the method's class type
2816223017Sdim        if (ResultClass->isSuperClassOf(CurrentClass))
2817239462Sdim          return Sema::RTC_Compatible;
2818223017Sdim      }
2819226633Sdim    } else {
2820226633Sdim      // Any Objective-C pointer type might be acceptable for a protocol
2821226633Sdim      // method; we just don't know.
2822239462Sdim      return Sema::RTC_Unknown;
2823223017Sdim    }
2824223017Sdim  }
2825223017Sdim
2826239462Sdim  return Sema::RTC_Incompatible;
2827223017Sdim}
2828223017Sdim
2829226633Sdimnamespace {
2830226633Sdim/// A helper class for searching for methods which a particular method
2831226633Sdim/// overrides.
2832226633Sdimclass OverrideSearch {
2833234353Sdimpublic:
2834226633Sdim  Sema &S;
2835226633Sdim  ObjCMethodDecl *Method;
2836234353Sdim  llvm::SmallPtrSet<ObjCMethodDecl*, 4> Overridden;
2837226633Sdim  bool Recursive;
2838226633Sdim
2839226633Sdimpublic:
2840226633Sdim  OverrideSearch(Sema &S, ObjCMethodDecl *method) : S(S), Method(method) {
2841226633Sdim    Selector selector = method->getSelector();
2842226633Sdim
2843226633Sdim    // Bypass this search if we've never seen an instance/class method
2844226633Sdim    // with this selector before.
2845226633Sdim    Sema::GlobalMethodPool::iterator it = S.MethodPool.find(selector);
2846226633Sdim    if (it == S.MethodPool.end()) {
2847243830Sdim      if (!S.getExternalSource()) return;
2848234353Sdim      S.ReadMethodPool(selector);
2849234353Sdim
2850234353Sdim      it = S.MethodPool.find(selector);
2851234353Sdim      if (it == S.MethodPool.end())
2852234353Sdim        return;
2853226633Sdim    }
2854226633Sdim    ObjCMethodList &list =
2855226633Sdim      method->isInstanceMethod() ? it->second.first : it->second.second;
2856226633Sdim    if (!list.Method) return;
2857226633Sdim
2858226633Sdim    ObjCContainerDecl *container
2859226633Sdim      = cast<ObjCContainerDecl>(method->getDeclContext());
2860226633Sdim
2861226633Sdim    // Prevent the search from reaching this container again.  This is
2862226633Sdim    // important with categories, which override methods from the
2863226633Sdim    // interface and each other.
2864239462Sdim    if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(container)) {
2865239462Sdim      searchFromContainer(container);
2866239462Sdim      if (ObjCInterfaceDecl *Interface = Category->getClassInterface())
2867239462Sdim        searchFromContainer(Interface);
2868239462Sdim    } else {
2869239462Sdim      searchFromContainer(container);
2870239462Sdim    }
2871223017Sdim  }
2872226633Sdim
2873234353Sdim  typedef llvm::SmallPtrSet<ObjCMethodDecl*, 128>::iterator iterator;
2874226633Sdim  iterator begin() const { return Overridden.begin(); }
2875226633Sdim  iterator end() const { return Overridden.end(); }
2876226633Sdim
2877226633Sdimprivate:
2878226633Sdim  void searchFromContainer(ObjCContainerDecl *container) {
2879226633Sdim    if (container->isInvalidDecl()) return;
2880226633Sdim
2881226633Sdim    switch (container->getDeclKind()) {
2882226633Sdim#define OBJCCONTAINER(type, base) \
2883226633Sdim    case Decl::type: \
2884226633Sdim      searchFrom(cast<type##Decl>(container)); \
2885226633Sdim      break;
2886226633Sdim#define ABSTRACT_DECL(expansion)
2887226633Sdim#define DECL(type, base) \
2888226633Sdim    case Decl::type:
2889226633Sdim#include "clang/AST/DeclNodes.inc"
2890226633Sdim      llvm_unreachable("not an ObjC container!");
2891226633Sdim    }
2892226633Sdim  }
2893226633Sdim
2894226633Sdim  void searchFrom(ObjCProtocolDecl *protocol) {
2895234353Sdim    if (!protocol->hasDefinition())
2896234353Sdim      return;
2897234353Sdim
2898226633Sdim    // A method in a protocol declaration overrides declarations from
2899226633Sdim    // referenced ("parent") protocols.
2900226633Sdim    search(protocol->getReferencedProtocols());
2901226633Sdim  }
2902226633Sdim
2903226633Sdim  void searchFrom(ObjCCategoryDecl *category) {
2904226633Sdim    // A method in a category declaration overrides declarations from
2905226633Sdim    // the main class and from protocols the category references.
2906239462Sdim    // The main class is handled in the constructor.
2907226633Sdim    search(category->getReferencedProtocols());
2908226633Sdim  }
2909226633Sdim
2910226633Sdim  void searchFrom(ObjCCategoryImplDecl *impl) {
2911226633Sdim    // A method in a category definition that has a category
2912226633Sdim    // declaration overrides declarations from the category
2913226633Sdim    // declaration.
2914226633Sdim    if (ObjCCategoryDecl *category = impl->getCategoryDecl()) {
2915226633Sdim      search(category);
2916239462Sdim      if (ObjCInterfaceDecl *Interface = category->getClassInterface())
2917239462Sdim        search(Interface);
2918226633Sdim
2919226633Sdim    // Otherwise it overrides declarations from the class.
2920239462Sdim    } else if (ObjCInterfaceDecl *Interface = impl->getClassInterface()) {
2921239462Sdim      search(Interface);
2922226633Sdim    }
2923226633Sdim  }
2924226633Sdim
2925226633Sdim  void searchFrom(ObjCInterfaceDecl *iface) {
2926226633Sdim    // A method in a class declaration overrides declarations from
2927234353Sdim    if (!iface->hasDefinition())
2928234353Sdim      return;
2929234353Sdim
2930226633Sdim    //   - categories,
2931249423Sdim    for (ObjCInterfaceDecl::known_categories_iterator
2932249423Sdim           cat = iface->known_categories_begin(),
2933249423Sdim           catEnd = iface->known_categories_end();
2934249423Sdim         cat != catEnd; ++cat) {
2935249423Sdim      search(*cat);
2936249423Sdim    }
2937226633Sdim
2938226633Sdim    //   - the super class, and
2939226633Sdim    if (ObjCInterfaceDecl *super = iface->getSuperClass())
2940226633Sdim      search(super);
2941226633Sdim
2942226633Sdim    //   - any referenced protocols.
2943226633Sdim    search(iface->getReferencedProtocols());
2944226633Sdim  }
2945226633Sdim
2946226633Sdim  void searchFrom(ObjCImplementationDecl *impl) {
2947226633Sdim    // A method in a class implementation overrides declarations from
2948226633Sdim    // the class interface.
2949239462Sdim    if (ObjCInterfaceDecl *Interface = impl->getClassInterface())
2950239462Sdim      search(Interface);
2951226633Sdim  }
2952226633Sdim
2953226633Sdim
2954226633Sdim  void search(const ObjCProtocolList &protocols) {
2955226633Sdim    for (ObjCProtocolList::iterator i = protocols.begin(), e = protocols.end();
2956226633Sdim         i != e; ++i)
2957226633Sdim      search(*i);
2958226633Sdim  }
2959226633Sdim
2960226633Sdim  void search(ObjCContainerDecl *container) {
2961226633Sdim    // Check for a method in this container which matches this selector.
2962226633Sdim    ObjCMethodDecl *meth = container->getMethod(Method->getSelector(),
2963249423Sdim                                                Method->isInstanceMethod(),
2964249423Sdim                                                /*AllowHidden=*/true);
2965226633Sdim
2966226633Sdim    // If we find one, record it and bail out.
2967226633Sdim    if (meth) {
2968226633Sdim      Overridden.insert(meth);
2969226633Sdim      return;
2970226633Sdim    }
2971226633Sdim
2972226633Sdim    // Otherwise, search for methods that a hypothetical method here
2973226633Sdim    // would have overridden.
2974226633Sdim
2975226633Sdim    // Note that we're now in a recursive case.
2976226633Sdim    Recursive = true;
2977226633Sdim
2978226633Sdim    searchFromContainer(container);
2979226633Sdim  }
2980226633Sdim};
2981223017Sdim}
2982223017Sdim
2983239462Sdimvoid Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod,
2984239462Sdim                                    ObjCInterfaceDecl *CurrentClass,
2985239462Sdim                                    ResultTypeCompatibilityKind RTC) {
2986239462Sdim  // Search for overridden methods and merge information down from them.
2987239462Sdim  OverrideSearch overrides(*this, ObjCMethod);
2988239462Sdim  // Keep track if the method overrides any method in the class's base classes,
2989239462Sdim  // its protocols, or its categories' protocols; we will keep that info
2990239462Sdim  // in the ObjCMethodDecl.
2991239462Sdim  // For this info, a method in an implementation is not considered as
2992239462Sdim  // overriding the same method in the interface or its categories.
2993239462Sdim  bool hasOverriddenMethodsInBaseOrProtocol = false;
2994239462Sdim  for (OverrideSearch::iterator
2995239462Sdim         i = overrides.begin(), e = overrides.end(); i != e; ++i) {
2996239462Sdim    ObjCMethodDecl *overridden = *i;
2997239462Sdim
2998251662Sdim    if (!hasOverriddenMethodsInBaseOrProtocol) {
2999251662Sdim      if (isa<ObjCProtocolDecl>(overridden->getDeclContext()) ||
3000251662Sdim          CurrentClass != overridden->getClassInterface() ||
3001251662Sdim          overridden->isOverriding()) {
3002251662Sdim        hasOverriddenMethodsInBaseOrProtocol = true;
3003239462Sdim
3004251662Sdim      } else if (isa<ObjCImplDecl>(ObjCMethod->getDeclContext())) {
3005251662Sdim        // OverrideSearch will return as "overridden" the same method in the
3006251662Sdim        // interface. For hasOverriddenMethodsInBaseOrProtocol, we need to
3007251662Sdim        // check whether a category of a base class introduced a method with the
3008251662Sdim        // same selector, after the interface method declaration.
3009251662Sdim        // To avoid unnecessary lookups in the majority of cases, we use the
3010251662Sdim        // extra info bits in GlobalMethodPool to check whether there were any
3011251662Sdim        // category methods with this selector.
3012251662Sdim        GlobalMethodPool::iterator It =
3013251662Sdim            MethodPool.find(ObjCMethod->getSelector());
3014251662Sdim        if (It != MethodPool.end()) {
3015251662Sdim          ObjCMethodList &List =
3016251662Sdim            ObjCMethod->isInstanceMethod()? It->second.first: It->second.second;
3017251662Sdim          unsigned CategCount = List.getBits();
3018251662Sdim          if (CategCount > 0) {
3019251662Sdim            // If the method is in a category we'll do lookup if there were at
3020251662Sdim            // least 2 category methods recorded, otherwise only one will do.
3021251662Sdim            if (CategCount > 1 ||
3022251662Sdim                !isa<ObjCCategoryImplDecl>(overridden->getDeclContext())) {
3023251662Sdim              OverrideSearch overrides(*this, overridden);
3024251662Sdim              for (OverrideSearch::iterator
3025251662Sdim                     OI= overrides.begin(), OE= overrides.end(); OI!=OE; ++OI) {
3026251662Sdim                ObjCMethodDecl *SuperOverridden = *OI;
3027251662Sdim                if (isa<ObjCProtocolDecl>(SuperOverridden->getDeclContext()) ||
3028251662Sdim                    CurrentClass != SuperOverridden->getClassInterface()) {
3029251662Sdim                  hasOverriddenMethodsInBaseOrProtocol = true;
3030251662Sdim                  overridden->setOverriding(true);
3031251662Sdim                  break;
3032251662Sdim                }
3033251662Sdim              }
3034251662Sdim            }
3035251662Sdim          }
3036251662Sdim        }
3037251662Sdim      }
3038251662Sdim    }
3039251662Sdim
3040239462Sdim    // Propagate down the 'related result type' bit from overridden methods.
3041239462Sdim    if (RTC != Sema::RTC_Incompatible && overridden->hasRelatedResultType())
3042239462Sdim      ObjCMethod->SetRelatedResultType();
3043239462Sdim
3044239462Sdim    // Then merge the declarations.
3045239462Sdim    mergeObjCMethodDecls(ObjCMethod, overridden);
3046239462Sdim
3047239462Sdim    if (ObjCMethod->isImplicit() && overridden->isImplicit())
3048239462Sdim      continue; // Conflicting properties are detected elsewhere.
3049239462Sdim
3050239462Sdim    // Check for overriding methods
3051239462Sdim    if (isa<ObjCInterfaceDecl>(ObjCMethod->getDeclContext()) ||
3052239462Sdim        isa<ObjCImplementationDecl>(ObjCMethod->getDeclContext()))
3053239462Sdim      CheckConflictingOverridingMethod(ObjCMethod, overridden,
3054239462Sdim              isa<ObjCProtocolDecl>(overridden->getDeclContext()));
3055239462Sdim
3056239462Sdim    if (CurrentClass && overridden->getDeclContext() != CurrentClass &&
3057239462Sdim        isa<ObjCInterfaceDecl>(overridden->getDeclContext()) &&
3058239462Sdim        !overridden->isImplicit() /* not meant for properties */) {
3059239462Sdim      ObjCMethodDecl::param_iterator ParamI = ObjCMethod->param_begin(),
3060239462Sdim                                          E = ObjCMethod->param_end();
3061239462Sdim      ObjCMethodDecl::param_iterator PrevI = overridden->param_begin(),
3062239462Sdim                                     PrevE = overridden->param_end();
3063239462Sdim      for (; ParamI != E && PrevI != PrevE; ++ParamI, ++PrevI) {
3064239462Sdim        assert(PrevI != overridden->param_end() && "Param mismatch");
3065239462Sdim        QualType T1 = Context.getCanonicalType((*ParamI)->getType());
3066239462Sdim        QualType T2 = Context.getCanonicalType((*PrevI)->getType());
3067239462Sdim        // If type of argument of method in this class does not match its
3068239462Sdim        // respective argument type in the super class method, issue warning;
3069239462Sdim        if (!Context.typesAreCompatible(T1, T2)) {
3070239462Sdim          Diag((*ParamI)->getLocation(), diag::ext_typecheck_base_super)
3071239462Sdim            << T1 << T2;
3072239462Sdim          Diag(overridden->getLocation(), diag::note_previous_declaration);
3073239462Sdim          break;
3074239462Sdim        }
3075239462Sdim      }
3076239462Sdim    }
3077239462Sdim  }
3078239462Sdim
3079239462Sdim  ObjCMethod->setOverriding(hasOverriddenMethodsInBaseOrProtocol);
3080239462Sdim}
3081239462Sdim
3082212904SdimDecl *Sema::ActOnMethodDeclaration(
3083218893Sdim    Scope *S,
3084193326Sed    SourceLocation MethodLoc, SourceLocation EndLoc,
3085226633Sdim    tok::TokenKind MethodType,
3086212904Sdim    ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
3087226633Sdim    ArrayRef<SourceLocation> SelectorLocs,
3088193326Sed    Selector Sel,
3089193326Sed    // optional arguments. The number of types/arguments is obtained
3090193326Sed    // from the Sel.getNumArgs().
3091193326Sed    ObjCArgInfo *ArgInfo,
3092207619Srdivacky    DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
3093193326Sed    AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
3094221345Sdim    bool isVariadic, bool MethodDefinition) {
3095193326Sed  // Make sure we can establish a context for the method.
3096226633Sdim  if (!CurContext->isObjCContainer()) {
3097193326Sed    Diag(MethodLoc, diag::error_missing_method_context);
3098212904Sdim    return 0;
3099193326Sed  }
3100226633Sdim  ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
3101226633Sdim  Decl *ClassDecl = cast<Decl>(OCD);
3102193326Sed  QualType resultDeclType;
3103198092Srdivacky
3104226633Sdim  bool HasRelatedResultType = false;
3105204962Srdivacky  TypeSourceInfo *ResultTInfo = 0;
3106193326Sed  if (ReturnType) {
3107204962Srdivacky    resultDeclType = GetTypeFromParser(ReturnType, &ResultTInfo);
3108198092Srdivacky
3109263508Sdim    if (CheckFunctionReturnType(resultDeclType, MethodLoc))
3110212904Sdim      return 0;
3111263508Sdim
3112226633Sdim    HasRelatedResultType = (resultDeclType == Context.getObjCInstanceType());
3113226633Sdim  } else { // get the type for "id".
3114193326Sed    resultDeclType = Context.getObjCIdType();
3115226633Sdim    Diag(MethodLoc, diag::warn_missing_method_return_type)
3116226633Sdim      << FixItHint::CreateInsertion(SelectorLocs.front(), "(id)");
3117226633Sdim  }
3118198092Srdivacky
3119198092Srdivacky  ObjCMethodDecl* ObjCMethod =
3120226633Sdim    ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel,
3121226633Sdim                           resultDeclType,
3122204962Srdivacky                           ResultTInfo,
3123226633Sdim                           CurContext,
3124193326Sed                           MethodType == tok::minus, isVariadic,
3125243830Sdim                           /*isPropertyAccessor=*/false,
3126226633Sdim                           /*isImplicitlyDeclared=*/false, /*isDefined=*/false,
3127223017Sdim                           MethodDeclKind == tok::objc_optional
3128223017Sdim                             ? ObjCMethodDecl::Optional
3129223017Sdim                             : ObjCMethodDecl::Required,
3130226633Sdim                           HasRelatedResultType);
3131198092Srdivacky
3132226633Sdim  SmallVector<ParmVarDecl*, 16> Params;
3133198092Srdivacky
3134193326Sed  for (unsigned i = 0, e = Sel.getNumArgs(); i != e; ++i) {
3135198893Srdivacky    QualType ArgType;
3136200583Srdivacky    TypeSourceInfo *DI;
3137198092Srdivacky
3138263508Sdim    if (!ArgInfo[i].Type) {
3139198893Srdivacky      ArgType = Context.getObjCIdType();
3140198893Srdivacky      DI = 0;
3141193326Sed    } else {
3142198893Srdivacky      ArgType = GetTypeFromParser(ArgInfo[i].Type, &DI);
3143193326Sed    }
3144198092Srdivacky
3145218893Sdim    LookupResult R(*this, ArgInfo[i].Name, ArgInfo[i].NameLoc,
3146218893Sdim                   LookupOrdinaryName, ForRedeclaration);
3147218893Sdim    LookupName(R, S);
3148218893Sdim    if (R.isSingleResult()) {
3149218893Sdim      NamedDecl *PrevDecl = R.getFoundDecl();
3150218893Sdim      if (S->isDeclScope(PrevDecl)) {
3151221345Sdim        Diag(ArgInfo[i].NameLoc,
3152221345Sdim             (MethodDefinition ? diag::warn_method_param_redefinition
3153221345Sdim                               : diag::warn_method_param_declaration))
3154218893Sdim          << ArgInfo[i].Name;
3155218893Sdim        Diag(PrevDecl->getLocation(),
3156218893Sdim             diag::note_previous_declaration);
3157218893Sdim      }
3158218893Sdim    }
3159218893Sdim
3160221345Sdim    SourceLocation StartLoc = DI
3161221345Sdim      ? DI->getTypeLoc().getBeginLoc()
3162221345Sdim      : ArgInfo[i].NameLoc;
3163198092Srdivacky
3164221345Sdim    ParmVarDecl* Param = CheckParameter(ObjCMethod, StartLoc,
3165221345Sdim                                        ArgInfo[i].NameLoc, ArgInfo[i].Name,
3166249423Sdim                                        ArgType, DI, SC_None);
3167198092Srdivacky
3168221345Sdim    Param->setObjCMethodScopeInfo(i);
3169221345Sdim
3170193326Sed    Param->setObjCDeclQualifier(
3171193326Sed      CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier()));
3172198092Srdivacky
3173193326Sed    // Apply the attributes to the parameter.
3174194613Sed    ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs);
3175198092Srdivacky
3176234353Sdim    if (Param->hasAttr<BlocksAttr>()) {
3177234353Sdim      Diag(Param->getLocation(), diag::err_block_on_nonlocal);
3178234353Sdim      Param->setInvalidDecl();
3179234353Sdim    }
3180218893Sdim    S->AddDecl(Param);
3181218893Sdim    IdResolver.AddDecl(Param);
3182218893Sdim
3183193326Sed    Params.push_back(Param);
3184193326Sed  }
3185218893Sdim
3186207619Srdivacky  for (unsigned i = 0, e = CNumArgs; i != e; ++i) {
3187212904Sdim    ParmVarDecl *Param = cast<ParmVarDecl>(CParamInfo[i].Param);
3188207619Srdivacky    QualType ArgType = Param->getType();
3189207619Srdivacky    if (ArgType.isNull())
3190207619Srdivacky      ArgType = Context.getObjCIdType();
3191207619Srdivacky    else
3192207619Srdivacky      // Perform the default array/function conversions (C99 6.7.5.3p[7,8]).
3193224145Sdim      ArgType = Context.getAdjustedParameterType(ArgType);
3194263508Sdim
3195207619Srdivacky    Param->setDeclContext(ObjCMethod);
3196207619Srdivacky    Params.push_back(Param);
3197207619Srdivacky  }
3198207619Srdivacky
3199226633Sdim  ObjCMethod->setMethodParams(Context, Params, SelectorLocs);
3200193326Sed  ObjCMethod->setObjCDeclQualifier(
3201193326Sed    CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));
3202193326Sed
3203193326Sed  if (AttrList)
3204194613Sed    ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList);
3205198092Srdivacky
3206218893Sdim  // Add the method now.
3207226633Sdim  const ObjCMethodDecl *PrevMethod = 0;
3208226633Sdim  if (ObjCImplDecl *ImpDecl = dyn_cast<ObjCImplDecl>(ClassDecl)) {
3209193326Sed    if (MethodType == tok::minus) {
3210195341Sed      PrevMethod = ImpDecl->getInstanceMethod(Sel);
3211195341Sed      ImpDecl->addInstanceMethod(ObjCMethod);
3212193326Sed    } else {
3213195341Sed      PrevMethod = ImpDecl->getClassMethod(Sel);
3214195341Sed      ImpDecl->addClassMethod(ObjCMethod);
3215193326Sed    }
3216223017Sdim
3217234353Sdim    ObjCMethodDecl *IMD = 0;
3218234353Sdim    if (ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface())
3219234353Sdim      IMD = IDecl->lookupMethod(ObjCMethod->getSelector(),
3220234353Sdim                                ObjCMethod->isInstanceMethod());
3221263508Sdim    if (IMD && IMD->hasAttr<ObjCRequiresSuperAttr>() &&
3222263508Sdim        !ObjCMethod->hasAttr<ObjCRequiresSuperAttr>()) {
3223263508Sdim      // merge the attribute into implementation.
3224263508Sdim      ObjCMethod->addAttr(
3225263508Sdim        new (Context) ObjCRequiresSuperAttr(ObjCMethod->getLocation(), Context));
3226263508Sdim    }
3227212904Sdim    if (ObjCMethod->hasAttrs() &&
3228234353Sdim        containsInvalidMethodImplAttribute(IMD, ObjCMethod->getAttrs())) {
3229234353Sdim      SourceLocation MethodLoc = IMD->getLocation();
3230234353Sdim      if (!getSourceManager().isInSystemHeader(MethodLoc)) {
3231234353Sdim        Diag(EndLoc, diag::warn_attribute_method_def);
3232234353Sdim        Diag(MethodLoc, diag::note_method_declared_at)
3233234353Sdim          << ObjCMethod->getDeclName();
3234234353Sdim      }
3235234353Sdim    }
3236218893Sdim  } else {
3237218893Sdim    cast<DeclContext>(ClassDecl)->addDecl(ObjCMethod);
3238193326Sed  }
3239226633Sdim
3240193326Sed  if (PrevMethod) {
3241193326Sed    // You can never have two method definitions with the same name.
3242193326Sed    Diag(ObjCMethod->getLocation(), diag::err_duplicate_method_decl)
3243193326Sed      << ObjCMethod->getDeclName();
3244193326Sed    Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
3245263508Sdim    ObjCMethod->setInvalidDecl();
3246263508Sdim    return ObjCMethod;
3247198092Srdivacky  }
3248198893Srdivacky
3249223017Sdim  // If this Objective-C method does not have a related result type, but we
3250223017Sdim  // are allowed to infer related result types, try to do so based on the
3251223017Sdim  // method family.
3252223017Sdim  ObjCInterfaceDecl *CurrentClass = dyn_cast<ObjCInterfaceDecl>(ClassDecl);
3253223017Sdim  if (!CurrentClass) {
3254223017Sdim    if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(ClassDecl))
3255223017Sdim      CurrentClass = Cat->getClassInterface();
3256223017Sdim    else if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(ClassDecl))
3257223017Sdim      CurrentClass = Impl->getClassInterface();
3258223017Sdim    else if (ObjCCategoryImplDecl *CatImpl
3259223017Sdim                                   = dyn_cast<ObjCCategoryImplDecl>(ClassDecl))
3260223017Sdim      CurrentClass = CatImpl->getClassInterface();
3261223017Sdim  }
3262226633Sdim
3263226633Sdim  ResultTypeCompatibilityKind RTC
3264226633Sdim    = CheckRelatedResultTypeCompatibility(*this, ObjCMethod, CurrentClass);
3265226633Sdim
3266239462Sdim  CheckObjCMethodOverrides(ObjCMethod, CurrentClass, RTC);
3267226633Sdim
3268224145Sdim  bool ARCError = false;
3269234353Sdim  if (getLangOpts().ObjCAutoRefCount)
3270249423Sdim    ARCError = CheckARCMethodDecl(ObjCMethod);
3271224145Sdim
3272226633Sdim  // Infer the related result type when possible.
3273239462Sdim  if (!ARCError && RTC == Sema::RTC_Compatible &&
3274226633Sdim      !ObjCMethod->hasRelatedResultType() &&
3275226633Sdim      LangOpts.ObjCInferRelatedResultType) {
3276223017Sdim    bool InferRelatedResultType = false;
3277223017Sdim    switch (ObjCMethod->getMethodFamily()) {
3278223017Sdim    case OMF_None:
3279223017Sdim    case OMF_copy:
3280223017Sdim    case OMF_dealloc:
3281226633Sdim    case OMF_finalize:
3282223017Sdim    case OMF_mutableCopy:
3283223017Sdim    case OMF_release:
3284223017Sdim    case OMF_retainCount:
3285224145Sdim    case OMF_performSelector:
3286223017Sdim      break;
3287223017Sdim
3288223017Sdim    case OMF_alloc:
3289223017Sdim    case OMF_new:
3290223017Sdim      InferRelatedResultType = ObjCMethod->isClassMethod();
3291223017Sdim      break;
3292223017Sdim
3293223017Sdim    case OMF_init:
3294223017Sdim    case OMF_autorelease:
3295223017Sdim    case OMF_retain:
3296223017Sdim    case OMF_self:
3297223017Sdim      InferRelatedResultType = ObjCMethod->isInstanceMethod();
3298223017Sdim      break;
3299223017Sdim    }
3300223017Sdim
3301226633Sdim    if (InferRelatedResultType)
3302223017Sdim      ObjCMethod->SetRelatedResultType();
3303223017Sdim  }
3304239462Sdim
3305239462Sdim  ActOnDocumentableDecl(ObjCMethod);
3306239462Sdim
3307212904Sdim  return ObjCMethod;
3308193326Sed}
3309193326Sed
3310193326Sedbool Sema::CheckObjCDeclScope(Decl *D) {
3311226633Sdim  // Following is also an error. But it is caused by a missing @end
3312226633Sdim  // and diagnostic is issued elsewhere.
3313234353Sdim  if (isa<ObjCContainerDecl>(CurContext->getRedeclContext()))
3314226633Sdim    return false;
3315234353Sdim
3316234353Sdim  // If we switched context to translation unit while we are still lexically in
3317234353Sdim  // an objc container, it means the parser missed emitting an error.
3318234353Sdim  if (isa<TranslationUnitDecl>(getCurLexicalContext()->getRedeclContext()))
3319234353Sdim    return false;
3320226633Sdim
3321193326Sed  Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
3322193326Sed  D->setInvalidDecl();
3323198092Srdivacky
3324193326Sed  return true;
3325193326Sed}
3326193326Sed
3327239462Sdim/// Called whenever \@defs(ClassName) is encountered in the source.  Inserts the
3328193326Sed/// instance variables of ClassName into Decls.
3329212904Sdimvoid Sema::ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart,
3330193326Sed                     IdentifierInfo *ClassName,
3331226633Sdim                     SmallVectorImpl<Decl*> &Decls) {
3332193326Sed  // Check that ClassName is a valid class
3333207619Srdivacky  ObjCInterfaceDecl *Class = getObjCInterfaceDecl(ClassName, DeclStart);
3334193326Sed  if (!Class) {
3335193326Sed    Diag(DeclStart, diag::err_undef_interface) << ClassName;
3336193326Sed    return;
3337193326Sed  }
3338239462Sdim  if (LangOpts.ObjCRuntime.isNonFragile()) {
3339193326Sed    Diag(DeclStart, diag::err_atdef_nonfragile_interface);
3340193326Sed    return;
3341193326Sed  }
3342198092Srdivacky
3343193326Sed  // Collect the instance variables
3344226633Sdim  SmallVector<const ObjCIvarDecl*, 32> Ivars;
3345212904Sdim  Context.DeepCollectObjCIvars(Class, true, Ivars);
3346193576Sed  // For each ivar, create a fresh ObjCAtDefsFieldDecl.
3347212904Sdim  for (unsigned i = 0; i < Ivars.size(); i++) {
3348226633Sdim    const FieldDecl* ID = cast<FieldDecl>(Ivars[i]);
3349212904Sdim    RecordDecl *Record = dyn_cast<RecordDecl>(TagD);
3350221345Sdim    Decl *FD = ObjCAtDefsFieldDecl::Create(Context, Record,
3351221345Sdim                                           /*FIXME: StartL=*/ID->getLocation(),
3352221345Sdim                                           ID->getLocation(),
3353193576Sed                                           ID->getIdentifier(), ID->getType(),
3354193576Sed                                           ID->getBitWidth());
3355212904Sdim    Decls.push_back(FD);
3356193576Sed  }
3357198092Srdivacky
3358193326Sed  // Introduce all of these fields into the appropriate scope.
3359226633Sdim  for (SmallVectorImpl<Decl*>::iterator D = Decls.begin();
3360193326Sed       D != Decls.end(); ++D) {
3361212904Sdim    FieldDecl *FD = cast<FieldDecl>(*D);
3362234353Sdim    if (getLangOpts().CPlusPlus)
3363193326Sed      PushOnScopeChains(cast<FieldDecl>(FD), S);
3364212904Sdim    else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD))
3365195341Sed      Record->addDecl(FD);
3366193326Sed  }
3367193326Sed}
3368193326Sed
3369207619Srdivacky/// \brief Build a type-check a new Objective-C exception variable declaration.
3370221345SdimVarDecl *Sema::BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType T,
3371221345Sdim                                      SourceLocation StartLoc,
3372221345Sdim                                      SourceLocation IdLoc,
3373221345Sdim                                      IdentifierInfo *Id,
3374207619Srdivacky                                      bool Invalid) {
3375207619Srdivacky  // ISO/IEC TR 18037 S6.7.3: "The type of an object with automatic storage
3376207619Srdivacky  // duration shall not be qualified by an address-space qualifier."
3377207619Srdivacky  // Since all parameters have automatic store duration, they can not have
3378207619Srdivacky  // an address space.
3379207619Srdivacky  if (T.getAddressSpace() != 0) {
3380221345Sdim    Diag(IdLoc, diag::err_arg_with_address_space);
3381207619Srdivacky    Invalid = true;
3382207619Srdivacky  }
3383207619Srdivacky
3384207619Srdivacky  // An @catch parameter must be an unqualified object pointer type;
3385207619Srdivacky  // FIXME: Recover from "NSObject foo" by inserting the * in "NSObject *foo"?
3386207619Srdivacky  if (Invalid) {
3387207619Srdivacky    // Don't do any further checking.
3388207619Srdivacky  } else if (T->isDependentType()) {
3389207619Srdivacky    // Okay: we don't know what this type will instantiate to.
3390207619Srdivacky  } else if (!T->isObjCObjectPointerType()) {
3391207619Srdivacky    Invalid = true;
3392221345Sdim    Diag(IdLoc ,diag::err_catch_param_not_objc_type);
3393207619Srdivacky  } else if (T->isObjCQualifiedIdType()) {
3394207619Srdivacky    Invalid = true;
3395221345Sdim    Diag(IdLoc, diag::err_illegal_qualifiers_on_catch_parm);
3396207619Srdivacky  }
3397207619Srdivacky
3398221345Sdim  VarDecl *New = VarDecl::Create(Context, CurContext, StartLoc, IdLoc, Id,
3399249423Sdim                                 T, TInfo, SC_None);
3400207619Srdivacky  New->setExceptionVariable(true);
3401207619Srdivacky
3402234353Sdim  // In ARC, infer 'retaining' for variables of retainable type.
3403234353Sdim  if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(New))
3404234353Sdim    Invalid = true;
3405234353Sdim
3406207619Srdivacky  if (Invalid)
3407207619Srdivacky    New->setInvalidDecl();
3408207619Srdivacky  return New;
3409207619Srdivacky}
3410207619Srdivacky
3411212904SdimDecl *Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
3412207619Srdivacky  const DeclSpec &DS = D.getDeclSpec();
3413207619Srdivacky
3414207619Srdivacky  // We allow the "register" storage class on exception variables because
3415207619Srdivacky  // GCC did, but we drop it completely. Any other storage class is an error.
3416207619Srdivacky  if (DS.getStorageClassSpec() == DeclSpec::SCS_register) {
3417207619Srdivacky    Diag(DS.getStorageClassSpecLoc(), diag::warn_register_objc_catch_parm)
3418207619Srdivacky      << FixItHint::CreateRemoval(SourceRange(DS.getStorageClassSpecLoc()));
3419251662Sdim  } else if (DeclSpec::SCS SCS = DS.getStorageClassSpec()) {
3420207619Srdivacky    Diag(DS.getStorageClassSpecLoc(), diag::err_storage_spec_on_catch_parm)
3421251662Sdim      << DeclSpec::getSpecifierName(SCS);
3422251662Sdim  }
3423251662Sdim  if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec())
3424251662Sdim    Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
3425251662Sdim         diag::err_invalid_thread)
3426251662Sdim     << DeclSpec::getSpecifierName(TSCS);
3427207619Srdivacky  D.getMutableDeclSpec().ClearStorageClassSpecs();
3428207619Srdivacky
3429249423Sdim  DiagnoseFunctionSpecifiers(D.getDeclSpec());
3430207619Srdivacky
3431207619Srdivacky  // Check that there are no default arguments inside the type of this
3432207619Srdivacky  // exception object (C++ only).
3433234353Sdim  if (getLangOpts().CPlusPlus)
3434207619Srdivacky    CheckExtraCXXDefaultArguments(D);
3435207619Srdivacky
3436224145Sdim  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
3437210299Sed  QualType ExceptionType = TInfo->getType();
3438207619Srdivacky
3439221345Sdim  VarDecl *New = BuildObjCExceptionDecl(TInfo, ExceptionType,
3440221345Sdim                                        D.getSourceRange().getBegin(),
3441221345Sdim                                        D.getIdentifierLoc(),
3442221345Sdim                                        D.getIdentifier(),
3443207619Srdivacky                                        D.isInvalidType());
3444207619Srdivacky
3445207619Srdivacky  // Parameter declarators cannot be qualified (C++ [dcl.meaning]p1).
3446207619Srdivacky  if (D.getCXXScopeSpec().isSet()) {
3447207619Srdivacky    Diag(D.getIdentifierLoc(), diag::err_qualified_objc_catch_parm)
3448207619Srdivacky      << D.getCXXScopeSpec().getRange();
3449207619Srdivacky    New->setInvalidDecl();
3450207619Srdivacky  }
3451207619Srdivacky
3452207619Srdivacky  // Add the parameter declaration into this scope.
3453212904Sdim  S->AddDecl(New);
3454207619Srdivacky  if (D.getIdentifier())
3455207619Srdivacky    IdResolver.AddDecl(New);
3456207619Srdivacky
3457207619Srdivacky  ProcessDeclAttributes(S, New, D);
3458207619Srdivacky
3459207619Srdivacky  if (New->hasAttr<BlocksAttr>())
3460207619Srdivacky    Diag(New->getLocation(), diag::err_block_on_nonlocal);
3461212904Sdim  return New;
3462207619Srdivacky}
3463207619Srdivacky
3464207619Srdivacky/// CollectIvarsToConstructOrDestruct - Collect those ivars which require
3465207619Srdivacky/// initialization.
3466212904Sdimvoid Sema::CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI,
3467226633Sdim                                SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
3468212904Sdim  for (ObjCIvarDecl *Iv = OI->all_declared_ivar_begin(); Iv;
3469212904Sdim       Iv= Iv->getNextIvar()) {
3470207619Srdivacky    QualType QT = Context.getBaseElementType(Iv->getType());
3471208600Srdivacky    if (QT->isRecordType())
3472212904Sdim      Ivars.push_back(Iv);
3473207619Srdivacky  }
3474207619Srdivacky}
3475207619Srdivacky
3476226633Sdimvoid Sema::DiagnoseUseOfUnimplementedSelectors() {
3477226633Sdim  // Load referenced selectors from the external source.
3478226633Sdim  if (ExternalSource) {
3479226633Sdim    SmallVector<std::pair<Selector, SourceLocation>, 4> Sels;
3480226633Sdim    ExternalSource->ReadReferencedSelectors(Sels);
3481226633Sdim    for (unsigned I = 0, N = Sels.size(); I != N; ++I)
3482226633Sdim      ReferencedSelectors[Sels[I].first] = Sels[I].second;
3483207619Srdivacky  }
3484226633Sdim
3485263508Sdim  DiagnoseMismatchedMethodsInGlobalPool();
3486263508Sdim
3487218893Sdim  // Warning will be issued only when selector table is
3488218893Sdim  // generated (which means there is at lease one implementation
3489218893Sdim  // in the TU). This is to match gcc's behavior.
3490218893Sdim  if (ReferencedSelectors.empty() ||
3491218893Sdim      !Context.AnyObjCImplementation())
3492212904Sdim    return;
3493212904Sdim  for (llvm::DenseMap<Selector, SourceLocation>::iterator S =
3494212904Sdim        ReferencedSelectors.begin(),
3495212904Sdim       E = ReferencedSelectors.end(); S != E; ++S) {
3496212904Sdim    Selector Sel = (*S).first;
3497212904Sdim    if (!LookupImplementedMethodInGlobalPool(Sel))
3498212904Sdim      Diag((*S).second, diag::warn_unimplemented_selector) << Sel;
3499212904Sdim  }
3500212904Sdim  return;
3501212904Sdim}
3502263508Sdim
3503263508SdimObjCIvarDecl *
3504263508SdimSema::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method,
3505263508Sdim                                     const ObjCPropertyDecl *&PDecl) const {
3506263508Sdim
3507263508Sdim  const ObjCInterfaceDecl *IDecl = Method->getClassInterface();
3508263508Sdim  if (!IDecl)
3509263508Sdim    return 0;
3510263508Sdim  Method = IDecl->lookupMethod(Method->getSelector(), true);
3511263508Sdim  if (!Method || !Method->isPropertyAccessor())
3512263508Sdim    return 0;
3513263508Sdim  if ((PDecl = Method->findPropertyDecl())) {
3514263508Sdim    if (!PDecl->getDeclContext())
3515263508Sdim      return 0;
3516263508Sdim    // Make sure property belongs to accessor's class and not to
3517263508Sdim    // one of its super classes.
3518263508Sdim    if (const ObjCInterfaceDecl *CID =
3519263508Sdim        dyn_cast<ObjCInterfaceDecl>(PDecl->getDeclContext()))
3520263508Sdim      if (CID != IDecl)
3521263508Sdim        return 0;
3522263508Sdim    return PDecl->getPropertyIvarDecl();
3523263508Sdim  }
3524263508Sdim  return 0;
3525263508Sdim}
3526263508Sdim
3527263508Sdimvoid Sema::DiagnoseUnusedBackingIvarInAccessor(Scope *S) {
3528263508Sdim  if (S->hasUnrecoverableErrorOccurred() || !S->isInObjcMethodScope())
3529263508Sdim    return;
3530263508Sdim
3531263508Sdim  const ObjCMethodDecl *CurMethod = getCurMethodDecl();
3532263508Sdim  if (!CurMethod)
3533263508Sdim    return;
3534263508Sdim  const ObjCPropertyDecl *PDecl;
3535263508Sdim  const ObjCIvarDecl *IV = GetIvarBackingPropertyAccessor(CurMethod, PDecl);
3536263508Sdim  if (IV && !IV->getBackingIvarReferencedInAccessor()) {
3537263508Sdim    Diag(getCurMethodDecl()->getLocation(), diag::warn_unused_property_backing_ivar)
3538263508Sdim    << IV->getDeclName();
3539263508Sdim    Diag(PDecl->getLocation(), diag::note_property_declare);
3540263508Sdim  }
3541263508Sdim}
3542