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"
16252723Sdim#include "clang/AST/ASTContext.h"
17252723Sdim#include "clang/AST/ASTMutationListener.h"
18252723Sdim#include "clang/AST/DeclObjC.h"
19193326Sed#include "clang/AST/Expr.h"
20224145Sdim#include "clang/AST/ExprObjC.h"
21224145Sdim#include "clang/Basic/SourceManager.h"
22252723Sdim#include "clang/Lex/Preprocessor.h"
23212904Sdim#include "clang/Sema/DeclSpec.h"
24252723Sdim#include "clang/Sema/ExternalSemaSource.h"
25252723Sdim#include "clang/Sema/Lookup.h"
26252723Sdim#include "clang/Sema/Scope.h"
27252723Sdim#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.
64235633Sdim    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
111226890Sdimvoid Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod,
112252723Sdim                                   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
152226890Sdim    if (ObjCMethodFamily Family = Overridden->getMethodFamily())
153226890Sdim      Diag(Overridden->getLocation(),
154252723Sdim           diag::note_related_result_type_family)
155252723Sdim        << /*overridden method*/ 0
156226890Sdim        << Family;
157226890Sdim    else
158226890Sdim      Diag(Overridden->getLocation(),
159226890Sdim           diag::note_related_result_type_overridden);
160223017Sdim  }
161235633Sdim  if (getLangOpts().ObjCAutoRefCount) {
162226890Sdim    if ((NewMethod->hasAttr<NSReturnsRetainedAttr>() !=
163226890Sdim         Overridden->hasAttr<NSReturnsRetainedAttr>())) {
164226890Sdim        Diag(NewMethod->getLocation(),
165226890Sdim             diag::err_nsreturns_retained_attribute_mismatch) << 1;
166226890Sdim        Diag(Overridden->getLocation(), diag::note_previous_decl)
167226890Sdim        << "method";
168223017Sdim    }
169226890Sdim    if ((NewMethod->hasAttr<NSReturnsNotRetainedAttr>() !=
170226890Sdim              Overridden->hasAttr<NSReturnsNotRetainedAttr>())) {
171226890Sdim        Diag(NewMethod->getLocation(),
172226890Sdim             diag::err_nsreturns_retained_attribute_mismatch) << 0;
173226890Sdim        Diag(Overridden->getLocation(), diag::note_previous_decl)
174226890Sdim        << "method";
175223017Sdim    }
176245431Sdim    ObjCMethodDecl::param_const_iterator oi = Overridden->param_begin(),
177245431Sdim                                         oe = Overridden->param_end();
178226890Sdim    for (ObjCMethodDecl::param_iterator
179226890Sdim           ni = NewMethod->param_begin(), ne = NewMethod->param_end();
180245431Sdim         ni != ne && oi != oe; ++ni, ++oi) {
181226890Sdim      const ParmVarDecl *oldDecl = (*oi);
182226890Sdim      ParmVarDecl *newDecl = (*ni);
183226890Sdim      if (newDecl->hasAttr<NSConsumedAttr>() !=
184226890Sdim          oldDecl->hasAttr<NSConsumedAttr>()) {
185226890Sdim        Diag(newDecl->getLocation(),
186226890Sdim             diag::err_nsconsumed_attribute_mismatch);
187226890Sdim        Diag(oldDecl->getLocation(), diag::note_previous_decl)
188226890Sdim          << "parameter";
189226890Sdim      }
190226890Sdim    }
191223017Sdim  }
192223017Sdim}
193223017Sdim
194224145Sdim/// \brief Check a method declaration for compatibility with the Objective-C
195224145Sdim/// ARC conventions.
196252723Sdimbool Sema::CheckARCMethodDecl(ObjCMethodDecl *method) {
197224145Sdim  ObjCMethodFamily family = method->getMethodFamily();
198224145Sdim  switch (family) {
199224145Sdim  case OMF_None:
200226890Sdim  case OMF_finalize:
201224145Sdim  case OMF_retain:
202224145Sdim  case OMF_release:
203224145Sdim  case OMF_autorelease:
204224145Sdim  case OMF_retainCount:
205224145Sdim  case OMF_self:
206226890Sdim  case OMF_performSelector:
207224145Sdim    return false;
208224145Sdim
209245431Sdim  case OMF_dealloc:
210252723Sdim    if (!Context.hasSameType(method->getResultType(), Context.VoidTy)) {
211245431Sdim      SourceRange ResultTypeRange;
212245431Sdim      if (const TypeSourceInfo *ResultTypeInfo
213245431Sdim          = method->getResultTypeSourceInfo())
214245431Sdim        ResultTypeRange = ResultTypeInfo->getTypeLoc().getSourceRange();
215245431Sdim      if (ResultTypeRange.isInvalid())
216252723Sdim        Diag(method->getLocation(), diag::error_dealloc_bad_result_type)
217245431Sdim          << method->getResultType()
218245431Sdim          << FixItHint::CreateInsertion(method->getSelectorLoc(0), "(void)");
219245431Sdim      else
220252723Sdim        Diag(method->getLocation(), diag::error_dealloc_bad_result_type)
221245431Sdim          << method->getResultType()
222245431Sdim          << FixItHint::CreateReplacement(ResultTypeRange, "void");
223245431Sdim      return true;
224245431Sdim    }
225245431Sdim    return false;
226245431Sdim
227224145Sdim  case OMF_init:
228224145Sdim    // If the method doesn't obey the init rules, don't bother annotating it.
229252723Sdim    if (checkInitMethod(method, QualType()))
230224145Sdim      return true;
231224145Sdim
232252723Sdim    method->addAttr(new (Context) NSConsumesSelfAttr(SourceLocation(),
233252723Sdim                                                     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
252252723Sdim  method->addAttr(new (Context) NSReturnsRetainedAttr(SourceLocation(),
253252723Sdim                                                      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)
264235633Sdim      S.Diag(ND->getLocation(), diag::note_method_declared_at)
265235633Sdim        << ND->getDeclName();
266218893Sdim    else
267218893Sdim      S.Diag(ND->getLocation(), diag::note_previous_decl) << "class";
268218893Sdim  }
269218893Sdim}
270218893Sdim
271226890Sdim/// AddAnyMethodToGlobalPool - Add any method, instance or factory to global
272226890Sdim/// pool.
273226890Sdimvoid Sema::AddAnyMethodToGlobalPool(Decl *D) {
274226890Sdim  ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
275226890Sdim
276226890Sdim  // If we don't have a valid method decl, simply return.
277226890Sdim  if (!MDecl)
278226890Sdim    return;
279226890Sdim  if (MDecl->isInstanceMethod())
280226890Sdim    AddInstanceMethodToGlobalPool(MDecl, true);
281226890Sdim  else
282226890Sdim    AddFactoryMethodToGlobalPool(MDecl, true);
283226890Sdim}
284226890Sdim
285245431Sdim/// HasExplicitOwnershipAttr - returns true when pointer to ObjC pointer
286245431Sdim/// has explicit ownership attribute; false otherwise.
287245431Sdimstatic bool
288245431SdimHasExplicitOwnershipAttr(Sema &S, ParmVarDecl *Param) {
289245431Sdim  QualType T = Param->getType();
290245431Sdim
291245431Sdim  if (const PointerType *PT = T->getAs<PointerType>()) {
292245431Sdim    T = PT->getPointeeType();
293245431Sdim  } else if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
294245431Sdim    T = RT->getPointeeType();
295245431Sdim  } else {
296245431Sdim    return true;
297245431Sdim  }
298245431Sdim
299245431Sdim  // If we have a lifetime qualifier, but it's local, we must have
300245431Sdim  // inferred it. So, it is implicit.
301245431Sdim  return !T.getLocalQualifiers().hasObjCLifetime();
302245431Sdim}
303245431Sdim
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) {
307245431Sdim  assert((getCurMethodDecl() == 0) && "Methodparsing confused");
308212904Sdim  ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
309245431Sdim
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
327263509Sdim  // The ObjC parser requires parameter names so there's no need to check.
328263509Sdim  CheckParmsForFunctionDef(MDecl->param_begin(), MDecl->param_end(),
329263509Sdim                           /*CheckParameterNames=*/false);
330263509Sdim
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() &&
336245431Sdim        getLangOpts().ObjCAutoRefCount &&
337245431Sdim        !HasExplicitOwnershipAttr(*this, Param))
338245431Sdim      Diag(Param->getLocation(), diag::warn_arc_strong_pointer_objc_pointer) <<
339245431Sdim            Param->getType();
340245431Sdim
341193326Sed    if ((*PI)->getIdentifier())
342193326Sed      PushOnScopeChains(*PI, FnBodyScope);
343218893Sdim  }
344224145Sdim
345224145Sdim  // In ARC, disallow definition of retain/release/autorelease/retainCount
346235633Sdim  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)
353263509Sdim        << 0 << MDecl->getSelector();
354224145Sdim      break;
355224145Sdim
356224145Sdim    case OMF_None:
357224145Sdim    case OMF_dealloc:
358226890Sdim    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
370226890Sdim  // Warn on deprecated methods under -Wdeprecated-implementations,
371226890Sdim  // and prepare for warning on missing super calls.
372226890Sdim  if (ObjCInterfaceDecl *IC = MDecl->getClassInterface()) {
373245431Sdim    ObjCMethodDecl *IMD =
374245431Sdim      IC->lookupMethod(MDecl->getSelector(), MDecl->isInstanceMethod());
375245431Sdim
376252723Sdim    if (IMD) {
377252723Sdim      ObjCImplDecl *ImplDeclOfMethodDef =
378252723Sdim        dyn_cast<ObjCImplDecl>(MDecl->getDeclContext());
379252723Sdim      ObjCContainerDecl *ContDeclOfMethodDecl =
380252723Sdim        dyn_cast<ObjCContainerDecl>(IMD->getDeclContext());
381252723Sdim      ObjCImplDecl *ImplDeclOfMethodDecl = 0;
382252723Sdim      if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ContDeclOfMethodDecl))
383252723Sdim        ImplDeclOfMethodDecl = OID->getImplementation();
384252723Sdim      else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(ContDeclOfMethodDecl))
385252723Sdim        ImplDeclOfMethodDecl = CD->getImplementation();
386252723Sdim      // No need to issue deprecated warning if deprecated mehod in class/category
387252723Sdim      // is being implemented in its own implementation (no overriding is involved).
388252723Sdim      if (!ImplDeclOfMethodDecl || ImplDeclOfMethodDecl != ImplDeclOfMethodDef)
389252723Sdim        DiagnoseObjCImplementedDeprecations(*this,
390218893Sdim                                          dyn_cast<NamedDecl>(IMD),
391218893Sdim                                          MDecl->getLocation(), 0);
392252723Sdim    }
393226890Sdim
394226890Sdim    // If this is "dealloc" or "finalize", set some bit here.
395226890Sdim    // Then in ActOnSuperMessage() (SemaExprObjC), set it back to false.
396226890Sdim    // Finally, in ActOnFinishFunctionBody() (SemaDecl), warn if flag is set.
397226890Sdim    // Only do this if the current class actually has a superclass.
398252723Sdim    if (const ObjCInterfaceDecl *SuperClass = IC->getSuperClass()) {
399245431Sdim      ObjCMethodFamily Family = MDecl->getMethodFamily();
400245431Sdim      if (Family == OMF_dealloc) {
401245431Sdim        if (!(getLangOpts().ObjCAutoRefCount ||
402245431Sdim              getLangOpts().getGC() == LangOptions::GCOnly))
403245431Sdim          getCurFunction()->ObjCShouldCallSuper = true;
404245431Sdim
405245431Sdim      } else if (Family == OMF_finalize) {
406245431Sdim        if (Context.getLangOpts().getGC() != LangOptions::NonGC)
407245431Sdim          getCurFunction()->ObjCShouldCallSuper = true;
408245431Sdim
409245431Sdim      } else {
410245431Sdim        const ObjCMethodDecl *SuperMethod =
411252723Sdim          SuperClass->lookupMethod(MDecl->getSelector(),
412252723Sdim                                   MDecl->isInstanceMethod());
413245431Sdim        getCurFunction()->ObjCShouldCallSuper =
414245431Sdim          (SuperMethod && SuperMethod->hasAttr<ObjCRequiresSuperAttr>());
415245431Sdim      }
416226890Sdim    }
417226890Sdim  }
418193326Sed}
419193326Sed
420235633Sdimnamespace {
421235633Sdim
422235633Sdim// Callback to only accept typo corrections that are Objective-C classes.
423235633Sdim// If an ObjCInterfaceDecl* is given to the constructor, then the validation
424235633Sdim// function will reject corrections to that class.
425235633Sdimclass ObjCInterfaceValidatorCCC : public CorrectionCandidateCallback {
426235633Sdim public:
427235633Sdim  ObjCInterfaceValidatorCCC() : CurrentIDecl(0) {}
428235633Sdim  explicit ObjCInterfaceValidatorCCC(ObjCInterfaceDecl *IDecl)
429235633Sdim      : CurrentIDecl(IDecl) {}
430235633Sdim
431235633Sdim  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
432235633Sdim    ObjCInterfaceDecl *ID = candidate.getCorrectionDeclAs<ObjCInterfaceDecl>();
433235633Sdim    return ID && !declaresSameEntity(ID, CurrentIDecl);
434235633Sdim  }
435235633Sdim
436235633Sdim private:
437235633Sdim  ObjCInterfaceDecl *CurrentIDecl;
438235633Sdim};
439235633Sdim
440235633Sdim}
441235633Sdim
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
460235633Sdim  // Create a declaration to describe this @interface.
461235633Sdim  ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
462263509Sdim
463263509Sdim  if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) {
464263509Sdim    // A previous decl with a different name is because of
465263509Sdim    // @compatibility_alias, for example:
466263509Sdim    // \code
467263509Sdim    //   @class NewImage;
468263509Sdim    //   @compatibility_alias OldImage NewImage;
469263509Sdim    // \endcode
470263509Sdim    // A lookup for 'OldImage' will return the 'NewImage' decl.
471263509Sdim    //
472263509Sdim    // In such a case use the real declaration name, instead of the alias one,
473263509Sdim    // otherwise we will break IdentifierResolver and redecls-chain invariants.
474263509Sdim    // FIXME: If necessary, add a bit to indicate that this ObjCInterfaceDecl
475263509Sdim    // has been aliased.
476263509Sdim    ClassName = PrevIDecl->getIdentifier();
477263509Sdim  }
478263509Sdim
479235633Sdim  ObjCInterfaceDecl *IDecl
480235633Sdim    = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName,
481235633Sdim                                PrevIDecl, ClassLoc);
482235633Sdim
483235633Sdim  if (PrevIDecl) {
484235633Sdim    // Class already seen. Was it a definition?
485235633Sdim    if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) {
486235633Sdim      Diag(AtInterfaceLoc, diag::err_duplicate_class_def)
487235633Sdim        << PrevIDecl->getDeclName();
488235633Sdim      Diag(Def->getLocation(), diag::note_previous_definition);
489193326Sed      IDecl->setInvalidDecl();
490193326Sed    }
491193326Sed  }
492235633Sdim
493235633Sdim  if (AttrList)
494235633Sdim    ProcessDeclAttributeList(TUScope, IDecl, AttrList);
495235633Sdim  PushOnScopeChains(IDecl, TUScope);
496198092Srdivacky
497235633Sdim  // Start the definition of this class. If we're in a redefinition case, there
498235633Sdim  // may already be a definition, so we'll end up adding to it.
499235633Sdim  if (!IDecl->hasDefinition())
500235633Sdim    IDecl->startDefinition();
501235633Sdim
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) {
508235633Sdim      // Try to correct for a typo in the superclass name without correcting
509235633Sdim      // to the class we're defining.
510235633Sdim      ObjCInterfaceValidatorCCC Validator(IDecl);
511235633Sdim      if (TypoCorrection Corrected = CorrectTypo(
512224145Sdim          DeclarationNameInfo(SuperName, SuperLoc), LookupOrdinaryName, TUScope,
513235633Sdim          NULL, Validator)) {
514263509Sdim        diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest)
515263509Sdim                                    << SuperName << ClassName);
516235633Sdim        PrevDecl = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>();
517202379Srdivacky      }
518202379Srdivacky    }
519202379Srdivacky
520235633Sdim    if (declaresSameEntity(PrevDecl, IDecl)) {
521198092Srdivacky      Diag(SuperLoc, diag::err_recursive_superclass)
522198092Srdivacky        << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
523235633Sdim      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()) {
539252723Sdim            if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface()) {
540198092Srdivacky              SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
541252723Sdim              // This handles the following case:
542252723Sdim              // @interface NewI @end
543252723Sdim              // typedef NewI DeprI __attribute__((deprecated("blah")))
544252723Sdim              // @interface SI : DeprI /* warn here */ @end
545252723Sdim              (void)DiagnoseUseOfDecl(const_cast<TypedefNameDecl*>(TDecl), SuperLoc);
546252723Sdim            }
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);
565235633Sdim        else if (RequireCompleteType(SuperLoc,
566245431Sdim                                  Context.getObjCInterfaceType(SuperClassDecl),
567245431Sdim                                     diag::err_forward_superclass,
568245431Sdim                                     SuperClassDecl->getDeclName(),
569245431Sdim                                     ClassName,
570245431Sdim                                     SourceRange(AtInterfaceLoc, ClassLoc))) {
571224145Sdim          SuperClassDecl = 0;
572224145Sdim        }
573193326Sed      }
574198092Srdivacky      IDecl->setSuperClass(SuperClassDecl);
575198092Srdivacky      IDecl->setSuperClassLoc(SuperLoc);
576235633Sdim      IDecl->setEndOfDefinitionLoc(SuperLoc);
577193326Sed    }
578193326Sed  } else { // we have a root class.
579235633Sdim    IDecl->setEndOfDefinitionLoc(ClassLoc);
580193326Sed  }
581198092Srdivacky
582212904Sdim  // Check then save referenced protocols.
583193326Sed  if (NumProtoRefs) {
584245431Sdim    IDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs,
585202879Srdivacky                           ProtoLocs, Context);
586235633Sdim    IDecl->setEndOfDefinitionLoc(EndProtoLoc);
587193326Sed  }
588198092Srdivacky
589193326Sed  CheckObjCDeclScope(IDecl);
590226890Sdim  return ActOnObjCContainerStartDefinition(IDecl);
591193326Sed}
592193326Sed
593263509Sdim/// ActOnTypedefedProtocols - this action finds protocol list as part of the
594263509Sdim/// typedef'ed use for a qualified super class and adds them to the list
595263509Sdim/// of the protocols.
596263509Sdimvoid Sema::ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs,
597263509Sdim                                   IdentifierInfo *SuperName,
598263509Sdim                                   SourceLocation SuperLoc) {
599263509Sdim  if (!SuperName)
600263509Sdim    return;
601263509Sdim  NamedDecl* IDecl = LookupSingleName(TUScope, SuperName, SuperLoc,
602263509Sdim                                      LookupOrdinaryName);
603263509Sdim  if (!IDecl)
604263509Sdim    return;
605263509Sdim
606263509Sdim  if (const TypedefNameDecl *TDecl = dyn_cast_or_null<TypedefNameDecl>(IDecl)) {
607263509Sdim    QualType T = TDecl->getUnderlyingType();
608263509Sdim    if (T->isObjCObjectType())
609263509Sdim      if (const ObjCObjectType *OPT = T->getAs<ObjCObjectType>())
610263509Sdim        for (ObjCObjectType::qual_iterator I = OPT->qual_begin(),
611263509Sdim             E = OPT->qual_end(); I != E; ++I)
612263509Sdim          ProtocolRefs.push_back(*I);
613263509Sdim  }
614263509Sdim}
615263509Sdim
616245431Sdim/// ActOnCompatibilityAlias - this action is called after complete parsing of
617245431Sdim/// a \@compatibility_alias declaration. It sets up the alias relationships.
618245431SdimDecl *Sema::ActOnCompatibilityAlias(SourceLocation AtLoc,
619245431Sdim                                    IdentifierInfo *AliasName,
620245431Sdim                                    SourceLocation AliasLocation,
621245431Sdim                                    IdentifierInfo *ClassName,
622245431Sdim                                    SourceLocation ClassLocation) {
623193326Sed  // Look for previous declaration of alias name
624207619Srdivacky  NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, AliasLocation,
625207619Srdivacky                                      LookupOrdinaryName, ForRedeclaration);
626193326Sed  if (ADecl) {
627263509Sdim    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      }
678235633Sdim
679235633Sdim      if (!PDecl->hasDefinition())
680235633Sdim        continue;
681235633Sdim
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");
702235633Sdim  ObjCProtocolDecl *PrevDecl = LookupProtocol(ProtocolName, ProtocolLoc,
703235633Sdim                                              ForRedeclaration);
704235633Sdim  ObjCProtocolDecl *PDecl = 0;
705235633Sdim  if (ObjCProtocolDecl *Def = PrevDecl? PrevDecl->getDefinition() : 0) {
706235633Sdim    // If we already have a definition, complain.
707235633Sdim    Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName;
708235633Sdim    Diag(Def->getLocation(), diag::note_previous_definition);
709235633Sdim
710235633Sdim    // Create a new protocol that is completely distinct from previous
711235633Sdim    // declarations, and do not make this protocol available for name lookup.
712235633Sdim    // That way, we'll end up completely ignoring the duplicate.
713235633Sdim    // FIXME: Can we turn this into an error?
714235633Sdim    PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName,
715235633Sdim                                     ProtocolLoc, AtProtoInterfaceLoc,
716235633Sdim                                     /*PrevDecl=*/0);
717235633Sdim    PDecl->startDefinition();
718235633Sdim  } else {
719235633Sdim    if (PrevDecl) {
720235633Sdim      // Check for circular dependencies among protocol declarations. This can
721235633Sdim      // only happen if this protocol was forward-declared.
722235633Sdim      ObjCList<ObjCProtocolDecl> PList;
723235633Sdim      PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context);
724235633Sdim      err = CheckForwardProtocolDeclarationForCircularDependency(
725235633Sdim              ProtocolName, ProtocolLoc, PrevDecl->getLocation(), PList);
726193326Sed    }
727198092Srdivacky
728235633Sdim    // Create the new declaration.
729226890Sdim    PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName,
730235633Sdim                                     ProtocolLoc, AtProtoInterfaceLoc,
731235633Sdim                                     /*PrevDecl=*/PrevDecl);
732235633Sdim
733193326Sed    PushOnScopeChains(PDecl, TUScope);
734235633Sdim    PDecl->startDefinition();
735193326Sed  }
736235633Sdim
737193326Sed  if (AttrList)
738194613Sed    ProcessDeclAttributeList(TUScope, PDecl, AttrList);
739235633Sdim
740235633Sdim  // Merge attributes from previous declarations.
741235633Sdim  if (PrevDecl)
742235633Sdim    mergeDeclAttributes(PDecl, PrevDecl);
743235633Sdim
744223017Sdim  if (!err && NumProtoRefs ) {
745193326Sed    /// Check then save referenced protocols.
746245431Sdim    PDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs,
747202879Srdivacky                           ProtoLocs, Context);
748193326Sed  }
749198092Srdivacky
750198092Srdivacky  CheckObjCDeclScope(PDecl);
751226890Sdim  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,
761226890Sdim                              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) {
766235633Sdim      DeclFilterCCC<ObjCProtocolDecl> Validator;
767224145Sdim      TypoCorrection Corrected = CorrectTypo(
768224145Sdim          DeclarationNameInfo(ProtocolId[i].first, ProtocolId[i].second),
769235633Sdim          LookupObjCProtocolName, TUScope, NULL, Validator);
770263509Sdim      if ((PDecl = Corrected.getCorrectionDeclAs<ObjCProtocolDecl>()))
771263509Sdim        diagnoseTypo(Corrected, PDiag(diag::err_undeclared_protocol_suggest)
772263509Sdim                                    << ProtocolId[i].first);
773202379Srdivacky    }
774202379Srdivacky
775202379Srdivacky    if (!PDecl) {
776193326Sed      Diag(ProtocolId[i].second, diag::err_undeclared_protocol)
777193326Sed        << ProtocolId[i].first;
778193326Sed      continue;
779193326Sed    }
780252723Sdim    // If this is a forward protocol declaration, get its definition.
781252723Sdim    if (!PDecl->isThisDeclarationADefinition() && PDecl->getDefinition())
782252723Sdim      PDecl = PDecl->getDefinition();
783252723Sdim
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.
788252723Sdim    // FIXME: Recover nicely in the hidden case.
789252723Sdim    if (WarnOnDeclarations &&
790252723Sdim        (!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
826245431Sdim/// ActOnForwardProtocolDeclaration - Handle \@protocol foo;
827235633SdimSema::DeclGroupPtrTy
828193326SedSema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
829193326Sed                                      const IdentifierLocPair *IdentList,
830193326Sed                                      unsigned NumElts,
831193326Sed                                      AttributeList *attrList) {
832235633Sdim  SmallVector<Decl *, 8> DeclsInGroup;
833193326Sed  for (unsigned i = 0; i != NumElts; ++i) {
834193326Sed    IdentifierInfo *Ident = IdentList[i].first;
835235633Sdim    ObjCProtocolDecl *PrevDecl = LookupProtocol(Ident, IdentList[i].second,
836235633Sdim                                                ForRedeclaration);
837235633Sdim    ObjCProtocolDecl *PDecl
838235633Sdim      = ObjCProtocolDecl::Create(Context, CurContext, Ident,
839235633Sdim                                 IdentList[i].second, AtProtocolLoc,
840235633Sdim                                 PrevDecl);
841235633Sdim
842235633Sdim    PushOnScopeChains(PDecl, TUScope);
843235633Sdim    CheckObjCDeclScope(PDecl);
844235633Sdim
845235633Sdim    if (attrList)
846194613Sed      ProcessDeclAttributeList(TUScope, PDecl, attrList);
847235633Sdim
848235633Sdim    if (PrevDecl)
849235633Sdim      mergeDeclAttributes(PDecl, PrevDecl);
850235633Sdim
851235633Sdim    DeclsInGroup.push_back(PDecl);
852193326Sed  }
853198092Srdivacky
854263509Sdim  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.
870235633Sdim
871235633Sdim  if (!IDecl
872235633Sdim      || RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
873245431Sdim                             diag::err_category_forward_interface,
874245431Sdim                             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,
879226890Sdim                                     ClassLoc, CategoryLoc, CategoryName,IDecl);
880204643Srdivacky    CDecl->setInvalidDecl();
881235633Sdim    CurContext->addDecl(CDecl);
882235633Sdim
883235633Sdim    if (!IDecl)
884235633Sdim      Diag(ClassLoc, diag::err_undef_interface) << ClassName;
885226890Sdim    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
896252723Sdim    if (ObjCCategoryDecl *Previous
897252723Sdim          = IDecl->FindCategoryDeclaration(CategoryName)) {
898252723Sdim      // Class extensions can be declared multiple times, categories cannot.
899252723Sdim      Diag(CategoryLoc, diag::warn_dup_category_def)
900252723Sdim        << ClassName << CategoryName;
901252723Sdim      Diag(Previous->getLocation(), diag::note_previous_definition);
902193326Sed    }
903193326Sed  }
904193326Sed
905226890Sdim  CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc,
906226890Sdim                                   ClassLoc, CategoryLoc, CategoryName, IDecl);
907226890Sdim  // FIXME: PushOnScopeChains?
908226890Sdim  CurContext->addDecl(CDecl);
909226890Sdim
910193326Sed  if (NumProtoRefs) {
911245431Sdim    CDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs,
912202879Srdivacky                           ProtoLocs, Context);
913198092Srdivacky    // Protocols in the class extension belong to the class.
914203955Srdivacky    if (CDecl->IsClassExtension())
915245431Sdim     IDecl->mergeClassExtensionProtocolList((ObjCProtocolDecl*const*)ProtoRefs,
916212904Sdim                                            NumProtoRefs, Context);
917193326Sed  }
918198092Srdivacky
919193326Sed  CheckObjCDeclScope(CDecl);
920226890Sdim  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;
932235633Sdim  if (IDecl && IDecl->hasDefinition()) {
933198092Srdivacky    CatIDecl = IDecl->FindCategoryDeclaration(CatName);
934198092Srdivacky    if (!CatIDecl) {
935198092Srdivacky      // Category @implementation with no corresponding @interface.
936198092Srdivacky      // Create and install one.
937235633Sdim      CatIDecl = ObjCCategoryDecl::Create(Context, CurContext, AtCatImplLoc,
938235633Sdim                                          ClassLoc, CatLoc,
939226890Sdim                                          CatName, IDecl);
940235633Sdim      CatIDecl->setImplicit();
941198092Srdivacky    }
942198092Srdivacky  }
943198092Srdivacky
944198092Srdivacky  ObjCCategoryImplDecl *CDecl =
945226890Sdim    ObjCCategoryImplDecl::Create(Context, CurContext, CatName, IDecl,
946235633Sdim                                 ClassLoc, AtCatImplLoc, CatLoc);
947193326Sed  /// Check that class of this category is already completely declared.
948235633Sdim  if (!IDecl) {
949193326Sed    Diag(ClassLoc, diag::err_undef_interface) << ClassName;
950226890Sdim    CDecl->setInvalidDecl();
951235633Sdim  } else if (RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
952235633Sdim                                 diag::err_undef_interface)) {
953235633Sdim    CDecl->setInvalidDecl();
954226890Sdim  }
955193326Sed
956193326Sed  // FIXME: PushOnScopeChains?
957195341Sed  CurContext->addDecl(CDecl);
958193326Sed
959226890Sdim  // If the interface is deprecated/unavailable, warn/error about it.
960226890Sdim  if (IDecl)
961226890Sdim    DiagnoseUseOfDecl(IDecl, ClassLoc);
962226890Sdim
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);
970263509Sdim      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);
982226890Sdim  return ActOnObjCContainerStartDefinition(CDecl);
983193326Sed}
984193326Sed
985212904SdimDecl *Sema::ActOnStartClassImplementation(
986193326Sed                      SourceLocation AtClassImplLoc,
987193326Sed                      IdentifierInfo *ClassName, SourceLocation ClassLoc,
988198092Srdivacky                      IdentifierInfo *SuperClassname,
989193326Sed                      SourceLocation SuperClassLoc) {
990263509Sdim  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))) {
999235633Sdim    RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
1000235633Sdim                        diag::warn_undef_interface);
1001202379Srdivacky  } else {
1002263509Sdim    // We did not find anything with the name ClassName; try to correct for
1003202379Srdivacky    // typos in the class name.
1004235633Sdim    ObjCInterfaceValidatorCCC Validator;
1005263509Sdim    TypoCorrection Corrected =
1006263509Sdim            CorrectTypo(DeclarationNameInfo(ClassName, ClassLoc),
1007263509Sdim                        LookupOrdinaryName, TUScope, NULL, Validator);
1008263509Sdim    if (Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) {
1009263509Sdim      // Suggest the (potentially) correct interface name. Don't provide a
1010263509Sdim      // code-modification hint or use the typo name for recovery, because
1011263509Sdim      // this is just a warning. The program may actually be correct.
1012263509Sdim      diagnoseTypo(Corrected,
1013263509Sdim                   PDiag(diag::warn_undef_interface_suggest) << ClassName,
1014263509Sdim                   /*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);
1032235633Sdim      if (SDecl && !SDecl->hasDefinition())
1033235633Sdim        SDecl = 0;
1034193326Sed      if (!SDecl)
1035193326Sed        Diag(SuperClassLoc, diag::err_undef_superclass)
1036193326Sed          << SuperClassname << ClassName;
1037235633Sdim      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,
1054235633Sdim                                      ClassName, /*PrevDecl=*/0, ClassLoc,
1055235633Sdim                                      true);
1056235633Sdim    IDecl->startDefinition();
1057235633Sdim    if (SDecl) {
1058235633Sdim      IDecl->setSuperClass(SDecl);
1059235633Sdim      IDecl->setSuperClassLoc(SuperClassLoc);
1060235633Sdim      IDecl->setEndOfDefinitionLoc(SuperClassLoc);
1061235633Sdim    } else {
1062235633Sdim      IDecl->setEndOfDefinitionLoc(ClassLoc);
1063235633Sdim    }
1064235633Sdim
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.
1070235633Sdim    if (!IDecl->hasDefinition())
1071235633Sdim      IDecl->startDefinition();
1072193326Sed  }
1073198092Srdivacky
1074198092Srdivacky  ObjCImplementationDecl* IMPDecl =
1075226890Sdim    ObjCImplementationDecl::Create(Context, CurContext, IDecl, SDecl,
1076252723Sdim                                   ClassLoc, AtClassImplLoc, SuperClassLoc);
1077198092Srdivacky
1078193326Sed  if (CheckObjCDeclScope(IMPDecl))
1079226890Sdim    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);
1087263509Sdim    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  }
1097226890Sdim  return ActOnObjCContainerStartDefinition(IMPDecl);
1098193326Sed}
1099193326Sed
1100235633SdimSema::DeclGroupPtrTy
1101235633SdimSema::ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef<Decl *> Decls) {
1102235633Sdim  SmallVector<Decl *, 64> DeclsInGroup;
1103235633Sdim  DeclsInGroup.reserve(Decls.size() + 1);
1104235633Sdim
1105235633Sdim  for (unsigned i = 0, e = Decls.size(); i != e; ++i) {
1106235633Sdim    Decl *Dcl = Decls[i];
1107235633Sdim    if (!Dcl)
1108235633Sdim      continue;
1109235633Sdim    if (Dcl->getDeclContext()->isFileContext())
1110235633Sdim      Dcl->setTopLevelDeclInObjCContainer();
1111235633Sdim    DeclsInGroup.push_back(Dcl);
1112235633Sdim  }
1113235633Sdim
1114235633Sdim  DeclsInGroup.push_back(ObjCImpDecl);
1115235633Sdim
1116263509Sdim  return BuildDeclaratorGroup(DeclsInGroup, false);
1117235633Sdim}
1118235633Sdim
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;
1126245431Sdim  /// Check case of non-existing \@interface decl.
1127245431Sdim  /// (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()) {
1130235633Sdim    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);
1134235633Sdim      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");
1145245431Sdim  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      }
1156263509Sdim      // Check class extensions (unnamed categories) for duplicate ivars.
1157263509Sdim      for (ObjCInterfaceDecl::visible_extensions_iterator
1158263509Sdim           Ext = IDecl->visible_extensions_begin(),
1159263509Sdim           ExtEnd = IDecl->visible_extensions_end();
1160263509Sdim         Ext != ExtEnd; ++Ext) {
1161263509Sdim        ObjCCategoryDecl *CDecl = *Ext;
1162263509Sdim        if (const ObjCIvarDecl *ClsExtIvar =
1163263509Sdim            CDecl->getIvarDecl(ImplIvar->getIdentifier())) {
1164263509Sdim          Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration);
1165263509Sdim          Diag(ClsExtIvar->getLocation(), diag::note_previous_definition);
1166263509Sdim          continue;
1167263509Sdim        }
1168263509Sdim      }
1169204643Srdivacky      // Instance ivar to Implementation's DeclContext.
1170204643Srdivacky      ImplIvar->setLexicalDeclContext(ImpDecl);
1171235633Sdim      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.
1189226890Sdim    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);
1194226890Sdim    } else if (ImplIvar->isBitField() && ClsIvar->isBitField() &&
1195226890Sdim               ImplIvar->getBitWidthValue(Context) !=
1196226890Sdim               ClsIvar->getBitWidthValue(Context)) {
1197226890Sdim      Diag(ImplIvar->getBitWidth()->getLocStart(),
1198226890Sdim           diag::err_conflicting_ivar_bitwidth) << ImplIvar->getIdentifier();
1199226890Sdim      Diag(ClsIvar->getBitWidth()->getLocStart(),
1200226890Sdim           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)
1214245431Sdim    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'.
1220252723Sdim  switch (method->getAvailability()) {
1221252723Sdim  case AR_Available:
1222252723Sdim  case AR_Deprecated:
1223252723Sdim    break;
1224252723Sdim
1225252723Sdim      // Don't warn about unavailable or not-yet-introduced methods.
1226252723Sdim  case AR_NotYetIntroduced:
1227252723Sdim  case AR_Unavailable:
1228224145Sdim    return;
1229193326Sed  }
1230252723Sdim
1231252723Sdim  // FIXME: For now ignore 'IncompleteImpl'.
1232252723Sdim  // Previously we grouped all unimplemented methods under a single
1233252723Sdim  // warning, but some users strongly voiced that they would prefer
1234252723Sdim  // separate warnings.  We will give that approach a try, as that
1235252723Sdim  // matches what we do with protocols.
1236252723Sdim
1237252723Sdim  Diag(ImpLoc, DiagID) << method->getDeclName();
1238252723Sdim
1239252723Sdim  // Issue a note to the original declaration.
1240252723Sdim  SourceLocation MethodLoc = method->getLocStart();
1241252723Sdim  if (MethodLoc.isValid())
1242252723Sdim    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
1316226890Sdimstatic bool CheckMethodOverrideReturn(Sema &S,
1317218893Sdim                                      ObjCMethodDecl *MethodImpl,
1318219077Sdim                                      ObjCMethodDecl *MethodDecl,
1319226890Sdim                                      bool IsProtocolMethodDecl,
1320226890Sdim                                      bool IsOverridingMode,
1321226890Sdim                                      bool Warn) {
1322219077Sdim  if (IsProtocolMethodDecl &&
1323219077Sdim      (MethodDecl->getObjCDeclQualifier() !=
1324219077Sdim       MethodImpl->getObjCDeclQualifier())) {
1325226890Sdim    if (Warn) {
1326226890Sdim        S.Diag(MethodImpl->getLocation(),
1327226890Sdim               (IsOverridingMode ?
1328226890Sdim                 diag::warn_conflicting_overriding_ret_type_modifiers
1329226890Sdim                 : diag::warn_conflicting_ret_type_modifiers))
1330226890Sdim          << MethodImpl->getDeclName()
1331226890Sdim          << getTypeRange(MethodImpl->getResultTypeSourceInfo());
1332226890Sdim        S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration)
1333226890Sdim          << getTypeRange(MethodDecl->getResultTypeSourceInfo());
1334226890Sdim    }
1335226890Sdim    else
1336226890Sdim      return false;
1337219077Sdim  }
1338219077Sdim
1339218893Sdim  if (S.Context.hasSameUnqualifiedType(MethodImpl->getResultType(),
1340219077Sdim                                       MethodDecl->getResultType()))
1341226890Sdim    return true;
1342226890Sdim  if (!Warn)
1343226890Sdim    return false;
1344218893Sdim
1345226890Sdim  unsigned DiagID =
1346226890Sdim    IsOverridingMode ? diag::warn_conflicting_overriding_ret_types
1347226890Sdim                     : 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))
1360226890Sdim        return false;
1361218893Sdim
1362226890Sdim      DiagID =
1363226890Sdim        IsOverridingMode ? diag::warn_non_covariant_overriding_ret_types
1364226890Sdim                          : 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());
1373226890Sdim  S.Diag(MethodDecl->getLocation(),
1374226890Sdim         IsOverridingMode ? diag::note_previous_declaration
1375226890Sdim                          : diag::note_previous_definition)
1376219077Sdim    << getTypeRange(MethodDecl->getResultTypeSourceInfo());
1377226890Sdim  return false;
1378218893Sdim}
1379218893Sdim
1380226890Sdimstatic bool CheckMethodOverrideParam(Sema &S,
1381218893Sdim                                     ObjCMethodDecl *MethodImpl,
1382219077Sdim                                     ObjCMethodDecl *MethodDecl,
1383218893Sdim                                     ParmVarDecl *ImplVar,
1384219077Sdim                                     ParmVarDecl *IfaceVar,
1385226890Sdim                                     bool IsProtocolMethodDecl,
1386226890Sdim                                     bool IsOverridingMode,
1387226890Sdim                                     bool Warn) {
1388219077Sdim  if (IsProtocolMethodDecl &&
1389219077Sdim      (ImplVar->getObjCDeclQualifier() !=
1390219077Sdim       IfaceVar->getObjCDeclQualifier())) {
1391226890Sdim    if (Warn) {
1392226890Sdim      if (IsOverridingMode)
1393226890Sdim        S.Diag(ImplVar->getLocation(),
1394226890Sdim               diag::warn_conflicting_overriding_param_modifiers)
1395226890Sdim            << getTypeRange(ImplVar->getTypeSourceInfo())
1396226890Sdim            << MethodImpl->getDeclName();
1397226890Sdim      else S.Diag(ImplVar->getLocation(),
1398226890Sdim             diag::warn_conflicting_param_modifiers)
1399226890Sdim          << getTypeRange(ImplVar->getTypeSourceInfo())
1400226890Sdim          << MethodImpl->getDeclName();
1401226890Sdim      S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration)
1402226890Sdim          << getTypeRange(IfaceVar->getTypeSourceInfo());
1403226890Sdim    }
1404226890Sdim    else
1405226890Sdim      return false;
1406219077Sdim  }
1407219077Sdim
1408218893Sdim  QualType ImplTy = ImplVar->getType();
1409218893Sdim  QualType IfaceTy = IfaceVar->getType();
1410219077Sdim
1411218893Sdim  if (S.Context.hasSameUnqualifiedType(ImplTy, IfaceTy))
1412226890Sdim    return true;
1413226890Sdim
1414226890Sdim  if (!Warn)
1415226890Sdim    return false;
1416226890Sdim  unsigned DiagID =
1417226890Sdim    IsOverridingMode ? diag::warn_conflicting_overriding_param_types
1418226890Sdim                     : 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))
1431226890Sdim        return false;
1432218893Sdim
1433226890Sdim      DiagID =
1434226890Sdim      IsOverridingMode ? diag::warn_non_contravariant_overriding_param_types
1435226890Sdim                       :  diag::warn_non_contravariant_param_types;
1436218893Sdim    }
1437218893Sdim  }
1438218893Sdim
1439218893Sdim  S.Diag(ImplVar->getLocation(), DiagID)
1440218893Sdim    << getTypeRange(ImplVar->getTypeSourceInfo())
1441218893Sdim    << MethodImpl->getDeclName() << IfaceTy << ImplTy;
1442226890Sdim  S.Diag(IfaceVar->getLocation(),
1443226890Sdim         (IsOverridingMode ? diag::note_previous_declaration
1444226890Sdim                        : diag::note_previous_definition))
1445218893Sdim    << getTypeRange(IfaceVar->getTypeSourceInfo());
1446226890Sdim  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:
1488226890Sdim  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
1514263509Sdim  S.Diag(impl->getLocation(), errorID) << int(familySelector) << int(reasonSelector);
1515263509Sdim  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) {
1523235633Sdim  if (getLangOpts().ObjCAutoRefCount &&
1524224145Sdim      checkMethodFamilyMismatch(*this, ImpMethodDecl, MethodDecl))
1525224145Sdim    return;
1526224145Sdim
1527219077Sdim  CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl,
1528226890Sdim                            IsProtocolMethodDecl, false,
1529226890Sdim                            true);
1530198092Srdivacky
1531193326Sed  for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
1532245431Sdim       IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(),
1533245431Sdim       EF = MethodDecl->param_end();
1534245431Sdim       IM != EM && IF != EF; ++IM, ++IF) {
1535219077Sdim    CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl, *IM, *IF,
1536226890Sdim                             IsProtocolMethodDecl, false, true);
1537226890Sdim  }
1538198092Srdivacky
1539219077Sdim  if (ImpMethodDecl->isVariadic() != MethodDecl->isVariadic()) {
1540226890Sdim    Diag(ImpMethodDecl->getLocation(),
1541226890Sdim         diag::warn_conflicting_variadic);
1542219077Sdim    Diag(MethodDecl->getLocation(), diag::note_previous_declaration);
1543208600Srdivacky  }
1544193326Sed}
1545193326Sed
1546226890Sdimvoid Sema::CheckConflictingOverridingMethod(ObjCMethodDecl *Method,
1547226890Sdim                                       ObjCMethodDecl *Overridden,
1548226890Sdim                                       bool IsProtocolMethodDecl) {
1549226890Sdim
1550226890Sdim  CheckMethodOverrideReturn(*this, Method, Overridden,
1551226890Sdim                            IsProtocolMethodDecl, true,
1552226890Sdim                            true);
1553226890Sdim
1554226890Sdim  for (ObjCMethodDecl::param_iterator IM = Method->param_begin(),
1555245431Sdim       IF = Overridden->param_begin(), EM = Method->param_end(),
1556245431Sdim       EF = Overridden->param_end();
1557245431Sdim       IM != EM && IF != EF; ++IM, ++IF) {
1558226890Sdim    CheckMethodOverrideParam(*this, Method, Overridden, *IM, *IF,
1559226890Sdim                             IsProtocolMethodDecl, true, true);
1560226890Sdim  }
1561226890Sdim
1562226890Sdim  if (Method->isVariadic() != Overridden->isVariadic()) {
1563226890Sdim    Diag(Method->getLocation(),
1564226890Sdim         diag::warn_conflicting_overriding_variadic);
1565226890Sdim    Diag(Overridden->getLocation(), diag::note_previous_declaration);
1566226890Sdim  }
1567226890Sdim}
1568226890Sdim
1569226890Sdim/// WarnExactTypedMethods - This routine issues a warning if method
1570226890Sdim/// implementation declaration matches exactly that of its declaration.
1571226890Sdimvoid Sema::WarnExactTypedMethods(ObjCMethodDecl *ImpMethodDecl,
1572226890Sdim                                 ObjCMethodDecl *MethodDecl,
1573226890Sdim                                 bool IsProtocolMethodDecl) {
1574226890Sdim  // don't issue warning when protocol method is optional because primary
1575226890Sdim  // class is not required to implement it and it is safe for protocol
1576226890Sdim  // to implement it.
1577226890Sdim  if (MethodDecl->getImplementationControl() == ObjCMethodDecl::Optional)
1578226890Sdim    return;
1579226890Sdim  // don't issue warning when primary class's method is
1580226890Sdim  // depecated/unavailable.
1581226890Sdim  if (MethodDecl->hasAttr<UnavailableAttr>() ||
1582226890Sdim      MethodDecl->hasAttr<DeprecatedAttr>())
1583226890Sdim    return;
1584226890Sdim
1585226890Sdim  bool match = CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl,
1586226890Sdim                                      IsProtocolMethodDecl, false, false);
1587226890Sdim  if (match)
1588226890Sdim    for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
1589245431Sdim         IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(),
1590245431Sdim         EF = MethodDecl->param_end();
1591245431Sdim         IM != EM && IF != EF; ++IM, ++IF) {
1592226890Sdim      match = CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl,
1593226890Sdim                                       *IM, *IF,
1594226890Sdim                                       IsProtocolMethodDecl, false, false);
1595226890Sdim      if (!match)
1596226890Sdim        break;
1597226890Sdim    }
1598226890Sdim  if (match)
1599226890Sdim    match = (ImpMethodDecl->isVariadic() == MethodDecl->isVariadic());
1600226890Sdim  if (match)
1601226890Sdim    match = !(MethodDecl->isClassMethod() &&
1602226890Sdim              MethodDecl->getSelector() == GetNullarySelector("load", Context));
1603226890Sdim
1604226890Sdim  if (match) {
1605226890Sdim    Diag(ImpMethodDecl->getLocation(),
1606226890Sdim         diag::warn_category_method_impl_match);
1607235633Sdim    Diag(MethodDecl->getLocation(), diag::note_method_declared_at)
1608235633Sdim      << MethodDecl->getDeclName();
1609226890Sdim  }
1610226890Sdim}
1611226890Sdim
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,
1623245431Sdim                                   const SelectorSet &InsMap,
1624245431Sdim                                   const SelectorSet &ClsMap,
1625206084Srdivacky                                   ObjCContainerDecl *CDecl) {
1626235633Sdim  ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl);
1627235633Sdim  ObjCInterfaceDecl *IDecl = C ? C->getClassInterface()
1628235633Sdim                               : dyn_cast<ObjCInterfaceDecl>(CDecl);
1629206084Srdivacky  assert (IDecl && "CheckProtocolMethodDefs - IDecl is null");
1630206084Srdivacky
1631193326Sed  ObjCInterfaceDecl *Super = IDecl->getSuperClass();
1632193326Sed  ObjCInterfaceDecl *NSIDecl = 0;
1633245431Sdim  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
1649252723Sdim  // If this is a forward protocol declaration, get its definition.
1650252723Sdim  if (!PDecl->isThisDeclarationADefinition() &&
1651252723Sdim      PDecl->getDefinition())
1652252723Sdim    PDecl = PDecl->getDefinition();
1653252723Sdim
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 &&
1665245431Sdim          !method->isPropertyAccessor() &&
1666245431Sdim          !InsMap.count(method->getSelector()) &&
1667245431Sdim          (!Super || !Super->lookupInstanceMethod(method->getSelector()))) {
1668235633Sdim            // If a method is not implemented in the category implementation but
1669235633Sdim            // has been declared in its primary class, superclass,
1670235633Sdim            // or in one of their protocols, no need to issue the warning.
1671235633Sdim            // This is because method will be implemented in the primary class
1672235633Sdim            // or one of its super class implementation.
1673235633Sdim
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.
1677235633Sdim            if (ObjCMethodDecl *MethodInClass =
1678235633Sdim                  IDecl->lookupInstanceMethod(method->getSelector(),
1679235633Sdim                                              true /*shallowCategoryLookup*/))
1680245431Sdim              if (C || MethodInClass->isPropertyAccessor())
1681235633Sdim                continue;
1682235633Sdim            unsigned DIAG = diag::warn_unimplemented_protocol_method;
1683235633Sdim            if (Diags.getDiagnosticLevel(DIAG, ImpLoc)
1684235633Sdim                != DiagnosticsEngine::Ignored) {
1685235633Sdim              WarnUndefinedMethod(ImpLoc, method, IncompleteImpl, DIAG);
1686235633Sdim              Diag(CDecl->getLocation(), diag::note_required_for_protocol_at)
1687235633Sdim                << 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()))) {
1699235633Sdim      // See above comment for instance method lookups.
1700235633Sdim      if (C && IDecl->lookupClassMethod(method->getSelector(),
1701235633Sdim                                        true /*shallowCategoryLookup*/))
1702235633Sdim        continue;
1703206084Srdivacky      unsigned DIAG = diag::warn_unimplemented_protocol_method;
1704226890Sdim      if (Diags.getDiagnosticLevel(DIAG, ImpLoc) !=
1705226890Sdim            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)
1715235633Sdim    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///
1721245431Sdimvoid Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap,
1722245431Sdim                                      const SelectorSet &ClsMap,
1723245431Sdim                                      SelectorSet &InsMapSeen,
1724245431Sdim                                      SelectorSet &ClsMapSeen,
1725193326Sed                                      ObjCImplDecl* IMPDecl,
1726193326Sed                                      ObjCContainerDecl* CDecl,
1727193326Sed                                      bool &IncompleteImpl,
1728226890Sdim                                      bool ImmediateClass,
1729235633Sdim                                      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) {
1734263509Sdim    if (!InsMapSeen.insert((*I)->getSelector()))
1735263509Sdim      continue;
1736245431Sdim    if (!(*I)->isPropertyAccessor() &&
1737193326Sed        !InsMap.count((*I)->getSelector())) {
1738193326Sed      if (ImmediateClass)
1739206084Srdivacky        WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl,
1740252723Sdim                            diag::warn_undef_method_impl);
1741193326Sed      continue;
1742198092Srdivacky    } else {
1743198092Srdivacky      ObjCMethodDecl *ImpMethodDecl =
1744226890Sdim        IMPDecl->getInstanceMethod((*I)->getSelector());
1745226890Sdim      assert(CDecl->getInstanceMethod((*I)->getSelector()) &&
1746226890Sdim             "Expected to find the method through lookup as well");
1747226890Sdim      ObjCMethodDecl *MethodDecl = *I;
1748193326Sed      // ImpMethodDecl may be null as in a @dynamic property.
1749226890Sdim      if (ImpMethodDecl) {
1750235633Sdim        if (!WarnCategoryMethodImpl)
1751226890Sdim          WarnConflictingTypedMethods(ImpMethodDecl, MethodDecl,
1752226890Sdim                                      isa<ObjCProtocolDecl>(CDecl));
1753245431Sdim        else if (!MethodDecl->isPropertyAccessor())
1754226890Sdim          WarnExactTypedMethods(ImpMethodDecl, MethodDecl,
1755235633Sdim                                isa<ObjCProtocolDecl>(CDecl));
1756226890Sdim      }
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.
1762263509Sdim  for (ObjCInterfaceDecl::classmeth_iterator I = CDecl->classmeth_begin(),
1763263509Sdim                                             E = CDecl->classmeth_end();
1764263509Sdim       I != E; ++I) {
1765263509Sdim    if (!ClsMapSeen.insert((*I)->getSelector()))
1766263509Sdim      continue;
1767193326Sed    if (!ClsMap.count((*I)->getSelector())) {
1768193326Sed      if (ImmediateClass)
1769206084Srdivacky        WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl,
1770252723Sdim                            diag::warn_undef_method_impl);
1771198092Srdivacky    } else {
1772195341Sed      ObjCMethodDecl *ImpMethodDecl =
1773195341Sed        IMPDecl->getClassMethod((*I)->getSelector());
1774226890Sdim      assert(CDecl->getClassMethod((*I)->getSelector()) &&
1775226890Sdim             "Expected to find the method through lookup as well");
1776226890Sdim      ObjCMethodDecl *MethodDecl = *I;
1777235633Sdim      if (!WarnCategoryMethodImpl)
1778226890Sdim        WarnConflictingTypedMethods(ImpMethodDecl, MethodDecl,
1779226890Sdim                                    isa<ObjCProtocolDecl>(CDecl));
1780226890Sdim      else
1781226890Sdim        WarnExactTypedMethods(ImpMethodDecl, MethodDecl,
1782235633Sdim                              isa<ObjCProtocolDecl>(CDecl));
1783193326Sed    }
1784193326Sed  }
1785218893Sdim
1786263509Sdim  if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl> (CDecl)) {
1787263509Sdim    // Also, check for methods declared in protocols inherited by
1788263509Sdim    // this protocol.
1789263509Sdim    for (ObjCProtocolDecl::protocol_iterator
1790263509Sdim          PI = PD->protocol_begin(), E = PD->protocol_end(); PI != E; ++PI)
1791263509Sdim      MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1792263509Sdim                                 IMPDecl, (*PI), IncompleteImpl, false,
1793263509Sdim                                 WarnCategoryMethodImpl);
1794263509Sdim  }
1795263509Sdim
1796193326Sed  if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
1797245431Sdim    // when checking that methods in implementation match their declaration,
1798245431Sdim    // i.e. when WarnCategoryMethodImpl is false, check declarations in class
1799245431Sdim    // extension; as well as those in categories.
1800252723Sdim    if (!WarnCategoryMethodImpl) {
1801252723Sdim      for (ObjCInterfaceDecl::visible_categories_iterator
1802252723Sdim             Cat = I->visible_categories_begin(),
1803252723Sdim           CatEnd = I->visible_categories_end();
1804252723Sdim           Cat != CatEnd; ++Cat) {
1805245431Sdim        MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1806252723Sdim                                   IMPDecl, *Cat, IncompleteImpl, false,
1807245431Sdim                                   WarnCategoryMethodImpl);
1808252723Sdim      }
1809252723Sdim    } else {
1810245431Sdim      // Also methods in class extensions need be looked at next.
1811252723Sdim      for (ObjCInterfaceDecl::visible_extensions_iterator
1812252723Sdim             Ext = I->visible_extensions_begin(),
1813252723Sdim             ExtEnd = I->visible_extensions_end();
1814252723Sdim           Ext != ExtEnd; ++Ext) {
1815245431Sdim        MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1816252723Sdim                                   IMPDecl, *Ext, IncompleteImpl, false,
1817245431Sdim                                   WarnCategoryMethodImpl);
1818252723Sdim      }
1819252723Sdim    }
1820252723Sdim
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,
1827235633Sdim                                 (*PI), IncompleteImpl, false,
1828235633Sdim                                 WarnCategoryMethodImpl);
1829226890Sdim
1830226890Sdim    // FIXME. For now, we are not checking for extact match of methods
1831226890Sdim    // in category implementation and its primary class's super class.
1832235633Sdim    if (!WarnCategoryMethodImpl && I->getSuperClass())
1833193326Sed      MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1834198092Srdivacky                                 IMPDecl,
1835193326Sed                                 I->getSuperClass(), IncompleteImpl, false);
1836193326Sed  }
1837193326Sed}
1838193326Sed
1839226890Sdim/// CheckCategoryVsClassMethodMatches - Checks that methods implemented in
1840226890Sdim/// category matches with those implemented in its primary class and
1841226890Sdim/// warns each time an exact match is found.
1842226890Sdimvoid Sema::CheckCategoryVsClassMethodMatches(
1843226890Sdim                                  ObjCCategoryImplDecl *CatIMPDecl) {
1844245431Sdim  SelectorSet InsMap, ClsMap;
1845226890Sdim
1846226890Sdim  for (ObjCImplementationDecl::instmeth_iterator
1847226890Sdim       I = CatIMPDecl->instmeth_begin(),
1848226890Sdim       E = CatIMPDecl->instmeth_end(); I!=E; ++I)
1849226890Sdim    InsMap.insert((*I)->getSelector());
1850226890Sdim
1851226890Sdim  for (ObjCImplementationDecl::classmeth_iterator
1852226890Sdim       I = CatIMPDecl->classmeth_begin(),
1853226890Sdim       E = CatIMPDecl->classmeth_end(); I != E; ++I)
1854226890Sdim    ClsMap.insert((*I)->getSelector());
1855226890Sdim  if (InsMap.empty() && ClsMap.empty())
1856226890Sdim    return;
1857226890Sdim
1858226890Sdim  // Get category's primary class.
1859226890Sdim  ObjCCategoryDecl *CatDecl = CatIMPDecl->getCategoryDecl();
1860226890Sdim  if (!CatDecl)
1861226890Sdim    return;
1862226890Sdim  ObjCInterfaceDecl *IDecl = CatDecl->getClassInterface();
1863226890Sdim  if (!IDecl)
1864226890Sdim    return;
1865245431Sdim  SelectorSet InsMapSeen, ClsMapSeen;
1866226890Sdim  bool IncompleteImpl = false;
1867226890Sdim  MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1868226890Sdim                             CatIMPDecl, IDecl,
1869235633Sdim                             IncompleteImpl, false,
1870235633Sdim                             true /*WarnCategoryMethodImpl*/);
1871226890Sdim}
1872226890Sdim
1873208600Srdivackyvoid Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
1874198092Srdivacky                                     ObjCContainerDecl* CDecl,
1875193326Sed                                     bool IncompleteImpl) {
1876245431Sdim  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.
1886235633Sdim  if (const ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl))
1887245431Sdim    if  (!(LangOpts.ObjCDefaultSynthProperties &&
1888245431Sdim           LangOpts.ObjCRuntime.isNonFragile()) ||
1889245431Sdim         IDecl->isObjCRequiresPropertyDefs())
1890252723Sdim      DiagnoseUnimplementedProperties(S, IMPDecl, CDecl);
1891202879Srdivacky
1892245431Sdim  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.
1900245431Sdim  SelectorSet InsMapSeen, ClsMapSeen;
1901198092Srdivacky  MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
1902198092Srdivacky                             IMPDecl, CDecl,
1903193326Sed                             IncompleteImpl, true);
1904226890Sdim
1905226890Sdim  // check all methods implemented in category against those declared
1906226890Sdim  // in its primary class.
1907226890Sdim  if (ObjCCategoryImplDecl *CatDecl =
1908226890Sdim        dyn_cast<ObjCCategoryImplDecl>(IMPDecl))
1909226890Sdim    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)
1923252723Sdim    for (ObjCInterfaceDecl::visible_extensions_iterator
1924252723Sdim           Ext = I->visible_extensions_begin(),
1925252723Sdim           ExtEnd = I->visible_extensions_end();
1926252723Sdim         Ext != ExtEnd; ++Ext) {
1927252723Sdim      ImplMethodsVsClassMethods(S, IMPDecl, *Ext, IncompleteImpl);
1928252723Sdim    }
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);
1937252723Sdim      DiagnoseUnimplementedProperties(S, IMPDecl, CDecl);
1938202879Srdivacky    }
1939193326Sed  } else
1940226890Sdim    llvm_unreachable("invalid ObjCContainerDecl type.");
1941193326Sed}
1942193326Sed
1943198092Srdivacky/// ActOnForwardClassDeclaration -
1944226890SdimSema::DeclGroupPtrTy
1945193326SedSema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
1946193326Sed                                   IdentifierInfo **IdentList,
1947199482Srdivacky                                   SourceLocation *IdentLocs,
1948193326Sed                                   unsigned NumElts) {
1949226890Sdim  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      //
1961235633Sdim      // Here we have chosen to ignore the forward class declaration
1962235633Sdim      // 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
1969235633Sdim        // to the underlying class. Just ignore the forward class with a warning
1970235633Sdim        // as this will force the intended behavior which is to lookup the typedef
1971235633Sdim        // name.
1972235633Sdim        if (isa<ObjCObjectType>(TDD->getUnderlyingType())) {
1973235633Sdim          Diag(AtClassLoc, diag::warn_forward_class_redefinition) << IdentList[i];
1974235633Sdim          Diag(PrevDecl->getLocation(), diag::note_previous_definition);
1975235633Sdim          continue;
1976235633Sdim        }
1977193326Sed      }
1978193326Sed    }
1979235633Sdim
1980235633Sdim    // Create a declaration to describe this forward declaration.
1981235633Sdim    ObjCInterfaceDecl *PrevIDecl
1982235633Sdim      = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
1983263509Sdim
1984263509Sdim    IdentifierInfo *ClassName = IdentList[i];
1985263509Sdim    if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) {
1986263509Sdim      // A previous decl with a different name is because of
1987263509Sdim      // @compatibility_alias, for example:
1988263509Sdim      // \code
1989263509Sdim      //   @class NewImage;
1990263509Sdim      //   @compatibility_alias OldImage NewImage;
1991263509Sdim      // \endcode
1992263509Sdim      // A lookup for 'OldImage' will return the 'NewImage' decl.
1993263509Sdim      //
1994263509Sdim      // In such a case use the real declaration name, instead of the alias one,
1995263509Sdim      // otherwise we will break IdentifierResolver and redecls-chain invariants.
1996263509Sdim      // FIXME: If necessary, add a bit to indicate that this ObjCInterfaceDecl
1997263509Sdim      // has been aliased.
1998263509Sdim      ClassName = PrevIDecl->getIdentifier();
1999263509Sdim    }
2000263509Sdim
2001235633Sdim    ObjCInterfaceDecl *IDecl
2002235633Sdim      = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
2003263509Sdim                                  ClassName, PrevIDecl, IdentLocs[i]);
2004235633Sdim    IDecl->setAtEndRange(IdentLocs[i]);
2005235633Sdim
2006235633Sdim    PushOnScopeChains(IDecl, TUScope);
2007235633Sdim    CheckObjCDeclScope(IDecl);
2008235633Sdim    DeclsInGroup.push_back(IDecl);
2009193326Sed  }
2010263509Sdim
2011263509Sdim  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
2053226890Sdim  // Make scalars agree in kind, except count bools as chars, and group
2054226890Sdim  // 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;
2059226890Sdim  if (leftSK == Type::STK_CPointer || leftSK == Type::STK_BlockPointer)
2060226890Sdim    leftSK = Type::STK_ObjCObjectPointer;
2061226890Sdim  if (rightSK == Type::STK_CPointer || rightSK == Type::STK_BlockPointer)
2062226890Sdim    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
2110252723Sdim  // If either is hidden, it is not considered to match.
2111252723Sdim  if (left->isHidden() || right->isHidden())
2112252723Sdim    return false;
2113252723Sdim
2114235633Sdim  if (getLangOpts().ObjCAutoRefCount &&
2115224145Sdim      (left->hasAttr<NSReturnsRetainedAttr>()
2116224145Sdim         != right->hasAttr<NSReturnsRetainedAttr>() ||
2117224145Sdim       left->hasAttr<NSConsumesSelfAttr>()
2118224145Sdim         != right->hasAttr<NSConsumesSelfAttr>()))
2119224145Sdim    return false;
2120224145Sdim
2121226890Sdim  ObjCMethodDecl::param_const_iterator
2122245431Sdim    li = left->param_begin(), le = left->param_end(), ri = right->param_begin(),
2123245431Sdim    re = right->param_end();
2124224145Sdim
2125245431Sdim  for (; li != le && ri != re; ++li, ++ri) {
2126224145Sdim    assert(ri != right->param_end() && "Param mismatch");
2127226890Sdim    const ParmVarDecl *lparm = *li, *rparm = *ri;
2128224145Sdim
2129224145Sdim    if (!matchTypes(Context, strategy, lparm->getType(), rparm->getType()))
2130193326Sed      return false;
2131224145Sdim
2132235633Sdim    if (getLangOpts().ObjCAutoRefCount &&
2133224145Sdim        lparm->hasAttr<NSConsumedAttr>() != rparm->hasAttr<NSConsumedAttr>())
2134193326Sed      return false;
2135193326Sed  }
2136193326Sed  return true;
2137193326Sed}
2138193326Sed
2139235633Sdimvoid Sema::addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method) {
2140252723Sdim  // Record at the head of the list whether there were 0, 1, or >= 2 methods
2141252723Sdim  // inside categories.
2142252723Sdim  if (ObjCCategoryDecl *
2143252723Sdim        CD = dyn_cast<ObjCCategoryDecl>(Method->getDeclContext()))
2144252723Sdim    if (!CD->IsClassExtension() && List->getBits() < 2)
2145252723Sdim        List->setBits(List->getBits()+1);
2146252723Sdim
2147235633Sdim  // If the list is empty, make it a singleton list.
2148235633Sdim  if (List->Method == 0) {
2149235633Sdim    List->Method = Method;
2150252723Sdim    List->setNext(0);
2151193326Sed    return;
2152193326Sed  }
2153235633Sdim
2154193326Sed  // We've seen a method with this name, see if we have already seen this type
2155193326Sed  // signature.
2156235633Sdim  ObjCMethodList *Previous = List;
2157252723Sdim  for (; List; Previous = List, List = List->getNext()) {
2158263509Sdim    // If we are building a module, keep all of the methods.
2159263509Sdim    if (getLangOpts().Modules && !getLangOpts().CurrentModule.empty())
2160263509Sdim      continue;
2161263509Sdim
2162235633Sdim    if (!MatchTwoMethodDeclarations(Method, List->Method))
2163235633Sdim      continue;
2164235633Sdim
2165235633Sdim    ObjCMethodDecl *PrevObjCMethod = List->Method;
2166224145Sdim
2167235633Sdim    // Propagate the 'defined' bit.
2168235633Sdim    if (Method->isDefined())
2169235633Sdim      PrevObjCMethod->setDefined(true);
2170235633Sdim
2171235633Sdim    // If a method is deprecated, push it in the global pool.
2172235633Sdim    // This is used for better diagnostics.
2173235633Sdim    if (Method->isDeprecated()) {
2174235633Sdim      if (!PrevObjCMethod->isDeprecated())
2175235633Sdim        List->Method = Method;
2176212904Sdim    }
2177235633Sdim    // If new method is unavailable, push it into global pool
2178235633Sdim    // unless previous one is deprecated.
2179235633Sdim    if (Method->isUnavailable()) {
2180235633Sdim      if (PrevObjCMethod->getAvailability() < AR_Deprecated)
2181235633Sdim        List->Method = Method;
2182235633Sdim    }
2183235633Sdim
2184235633Sdim    return;
2185224145Sdim  }
2186235633Sdim
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>();
2190252723Sdim  Previous->setNext(new (Mem) ObjCMethodList(Method, 0));
2191193326Sed}
2192193326Sed
2193235633Sdim/// \brief Read the contents of the method pool for a given selector from
2194235633Sdim/// external storage.
2195235633Sdimvoid Sema::ReadMethodPool(Selector Sel) {
2196235633Sdim  assert(ExternalSource && "We need an external AST source");
2197235633Sdim  ExternalSource->ReadMethodPool(Sel);
2198235633Sdim}
2199235633Sdim
2200235633Sdimvoid Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl,
2201235633Sdim                                 bool instance) {
2202235633Sdim  // Ignore methods of invalid containers.
2203235633Sdim  if (cast<Decl>(Method->getDeclContext())->isInvalidDecl())
2204235633Sdim    return;
2205235633Sdim
2206235633Sdim  if (ExternalSource)
2207235633Sdim    ReadMethodPool(Method->getSelector());
2208235633Sdim
2209235633Sdim  GlobalMethodPool::iterator Pos = MethodPool.find(Method->getSelector());
2210235633Sdim  if (Pos == MethodPool.end())
2211235633Sdim    Pos = MethodPool.insert(std::make_pair(Method->getSelector(),
2212235633Sdim                                           GlobalMethods())).first;
2213235633Sdim
2214235633Sdim  Method->setDefined(impl);
2215235633Sdim
2216235633Sdim  ObjCMethodList &Entry = instance ? Pos->second.first : Pos->second.second;
2217235633Sdim  addMethodToGlobalList(&Entry, Method);
2218235633Sdim}
2219235633Sdim
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) {
2242235633Sdim  if (ExternalSource)
2243235633Sdim    ReadMethodPool(Sel);
2244235633Sdim
2245212904Sdim  GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
2246235633Sdim  if (Pos == MethodPool.end())
2247235633Sdim    return 0;
2248193326Sed
2249252723Sdim  // Gather the non-hidden methods.
2250212904Sdim  ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second;
2251263509Sdim  SmallVector<ObjCMethodDecl *, 4> Methods;
2252252723Sdim  for (ObjCMethodList *M = &MethList; M; M = M->getNext()) {
2253252723Sdim    if (M->Method && !M->Method->isHidden()) {
2254252723Sdim      // If we're not supposed to warn about mismatches, we're done.
2255252723Sdim      if (!warn)
2256252723Sdim        return M->Method;
2257198092Srdivacky
2258252723Sdim      Methods.push_back(M->Method);
2259252723Sdim    }
2260252723Sdim  }
2261224145Sdim
2262252723Sdim  // If there aren't any visible methods, we're done.
2263252723Sdim  // FIXME: Recover if there are any known-but-hidden methods?
2264252723Sdim  if (Methods.empty())
2265252723Sdim    return 0;
2266252723Sdim
2267252723Sdim  if (Methods.size() == 1)
2268252723Sdim    return Methods[0];
2269252723Sdim
2270252723Sdim  // We found multiple methods, so we may have to complain.
2271252723Sdim  bool issueDiagnostic = false, issueError = false;
2272252723Sdim
2273252723Sdim  // We support a warning which complains about *any* difference in
2274252723Sdim  // method signature.
2275252723Sdim  bool strictSelectorMatch =
2276252723Sdim    (receiverIdOrClass && warn &&
2277252723Sdim     (Diags.getDiagnosticLevel(diag::warn_strict_multiple_method_decl,
2278252723Sdim                               R.getBegin())
2279252723Sdim        != DiagnosticsEngine::Ignored));
2280252723Sdim  if (strictSelectorMatch) {
2281252723Sdim    for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
2282252723Sdim      if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_strict)) {
2283252723Sdim        issueDiagnostic = true;
2284252723Sdim        break;
2285212904Sdim      }
2286252723Sdim    }
2287252723Sdim  }
2288193326Sed
2289252723Sdim  // If we didn't see any strict differences, we won't see any loose
2290252723Sdim  // differences.  In ARC, however, we also need to check for loose
2291252723Sdim  // mismatches, because most of them are errors.
2292252723Sdim  if (!strictSelectorMatch ||
2293252723Sdim      (issueDiagnostic && getLangOpts().ObjCAutoRefCount))
2294252723Sdim    for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
2295252723Sdim      // This checks if the methods differ in type mismatch.
2296252723Sdim      if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_loose) &&
2297252723Sdim          !isAcceptableMethodMismatch(Methods[0], Methods[I])) {
2298252723Sdim        issueDiagnostic = true;
2299252723Sdim        if (getLangOpts().ObjCAutoRefCount)
2300252723Sdim          issueError = true;
2301252723Sdim        break;
2302212904Sdim      }
2303252723Sdim    }
2304193326Sed
2305252723Sdim  if (issueDiagnostic) {
2306252723Sdim    if (issueError)
2307252723Sdim      Diag(R.getBegin(), diag::err_arc_multiple_method_decl) << Sel << R;
2308252723Sdim    else if (strictSelectorMatch)
2309252723Sdim      Diag(R.getBegin(), diag::warn_strict_multiple_method_decl) << Sel << R;
2310252723Sdim    else
2311252723Sdim      Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
2312224145Sdim
2313252723Sdim    Diag(Methods[0]->getLocStart(),
2314252723Sdim         issueError ? diag::note_possibility : diag::note_using)
2315252723Sdim      << Methods[0]->getSourceRange();
2316252723Sdim    for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
2317252723Sdim      Diag(Methods[I]->getLocStart(), diag::note_also_found)
2318252723Sdim        << Methods[I]->getSourceRange();
2319193326Sed  }
2320252723Sdim  }
2321252723Sdim  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
2338263509Sdimstatic void
2339263509SdimHelperSelectorsForTypoCorrection(
2340263509Sdim                      SmallVectorImpl<const ObjCMethodDecl *> &BestMethod,
2341263509Sdim                      StringRef Typo, const ObjCMethodDecl * Method) {
2342263509Sdim  const unsigned MaxEditDistance = 1;
2343263509Sdim  unsigned BestEditDistance = MaxEditDistance + 1;
2344263509Sdim  std::string MethodName = Method->getSelector().getAsString();
2345263509Sdim
2346263509Sdim  unsigned MinPossibleEditDistance = abs((int)MethodName.size() - (int)Typo.size());
2347263509Sdim  if (MinPossibleEditDistance > 0 &&
2348263509Sdim      Typo.size() / MinPossibleEditDistance < 1)
2349263509Sdim    return;
2350263509Sdim  unsigned EditDistance = Typo.edit_distance(MethodName, true, MaxEditDistance);
2351263509Sdim  if (EditDistance > MaxEditDistance)
2352263509Sdim    return;
2353263509Sdim  if (EditDistance == BestEditDistance)
2354263509Sdim    BestMethod.push_back(Method);
2355263509Sdim  else if (EditDistance < BestEditDistance) {
2356263509Sdim    BestMethod.clear();
2357263509Sdim    BestMethod.push_back(Method);
2358263509Sdim  }
2359263509Sdim}
2360263509Sdim
2361263509Sdimstatic bool HelperIsMethodInObjCType(Sema &S, Selector Sel,
2362263509Sdim                                     QualType ObjectType) {
2363263509Sdim  if (ObjectType.isNull())
2364263509Sdim    return true;
2365263509Sdim  if (S.LookupMethodInObjectType(Sel, ObjectType, true/*Instance method*/))
2366263509Sdim    return true;
2367263509Sdim  return S.LookupMethodInObjectType(Sel, ObjectType, false/*Class method*/) != 0;
2368263509Sdim}
2369263509Sdim
2370263509Sdimconst ObjCMethodDecl *
2371263509SdimSema::SelectorsForTypoCorrection(Selector Sel,
2372263509Sdim                                 QualType ObjectType) {
2373263509Sdim  unsigned NumArgs = Sel.getNumArgs();
2374263509Sdim  SmallVector<const ObjCMethodDecl *, 8> Methods;
2375263509Sdim  bool ObjectIsId = true, ObjectIsClass = true;
2376263509Sdim  if (ObjectType.isNull())
2377263509Sdim    ObjectIsId = ObjectIsClass = false;
2378263509Sdim  else if (!ObjectType->isObjCObjectPointerType())
2379263509Sdim    return 0;
2380263509Sdim  else if (const ObjCObjectPointerType *ObjCPtr =
2381263509Sdim           ObjectType->getAsObjCInterfacePointerType()) {
2382263509Sdim    ObjectType = QualType(ObjCPtr->getInterfaceType(), 0);
2383263509Sdim    ObjectIsId = ObjectIsClass = false;
2384263509Sdim  }
2385263509Sdim  else if (ObjectType->isObjCIdType() || ObjectType->isObjCQualifiedIdType())
2386263509Sdim    ObjectIsClass = false;
2387263509Sdim  else if (ObjectType->isObjCClassType() || ObjectType->isObjCQualifiedClassType())
2388263509Sdim    ObjectIsId = false;
2389263509Sdim  else
2390263509Sdim    return 0;
2391263509Sdim
2392263509Sdim  for (GlobalMethodPool::iterator b = MethodPool.begin(),
2393263509Sdim       e = MethodPool.end(); b != e; b++) {
2394263509Sdim    // instance methods
2395263509Sdim    for (ObjCMethodList *M = &b->second.first; M; M=M->getNext())
2396263509Sdim      if (M->Method &&
2397263509Sdim          (M->Method->getSelector().getNumArgs() == NumArgs) &&
2398263509Sdim          (M->Method->getSelector() != Sel)) {
2399263509Sdim        if (ObjectIsId)
2400263509Sdim          Methods.push_back(M->Method);
2401263509Sdim        else if (!ObjectIsClass &&
2402263509Sdim                 HelperIsMethodInObjCType(*this, M->Method->getSelector(), ObjectType))
2403263509Sdim          Methods.push_back(M->Method);
2404263509Sdim      }
2405263509Sdim    // class methods
2406263509Sdim    for (ObjCMethodList *M = &b->second.second; M; M=M->getNext())
2407263509Sdim      if (M->Method &&
2408263509Sdim          (M->Method->getSelector().getNumArgs() == NumArgs) &&
2409263509Sdim          (M->Method->getSelector() != Sel)) {
2410263509Sdim        if (ObjectIsClass)
2411263509Sdim          Methods.push_back(M->Method);
2412263509Sdim        else if (!ObjectIsId &&
2413263509Sdim                 HelperIsMethodInObjCType(*this, M->Method->getSelector(), ObjectType))
2414263509Sdim          Methods.push_back(M->Method);
2415263509Sdim      }
2416263509Sdim  }
2417263509Sdim
2418263509Sdim  SmallVector<const ObjCMethodDecl *, 8> SelectedMethods;
2419263509Sdim  for (unsigned i = 0, e = Methods.size(); i < e; i++) {
2420263509Sdim    HelperSelectorsForTypoCorrection(SelectedMethods,
2421263509Sdim                                     Sel.getAsString(), Methods[i]);
2422263509Sdim  }
2423263509Sdim  return (SelectedMethods.size() == 1) ? SelectedMethods[0] : NULL;
2424263509Sdim}
2425263509Sdim
2426263509Sdimstatic void
2427263509SdimHelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S,
2428263509Sdim                                              ObjCMethodList &MethList) {
2429263509Sdim  ObjCMethodList *M = &MethList;
2430263509Sdim  ObjCMethodDecl *TargetMethod = M->Method;
2431263509Sdim  while (TargetMethod &&
2432263509Sdim         isa<ObjCImplDecl>(TargetMethod->getDeclContext())) {
2433263509Sdim    M = M->getNext();
2434263509Sdim    TargetMethod = M ? M->Method : 0;
2435263509Sdim  }
2436263509Sdim  if (!TargetMethod)
2437263509Sdim    return;
2438263509Sdim  bool FirstTime = true;
2439263509Sdim  for (M = M->getNext(); M; M=M->getNext()) {
2440263509Sdim    ObjCMethodDecl *MatchingMethodDecl = M->Method;
2441263509Sdim    if (isa<ObjCImplDecl>(MatchingMethodDecl->getDeclContext()))
2442263509Sdim      continue;
2443263509Sdim    if (!S.MatchTwoMethodDeclarations(TargetMethod,
2444263509Sdim                                      MatchingMethodDecl, Sema::MMS_loose)) {
2445263509Sdim      if (FirstTime) {
2446263509Sdim        FirstTime = false;
2447263509Sdim        S.Diag(TargetMethod->getLocation(), diag::warning_multiple_selectors)
2448263509Sdim        << TargetMethod->getSelector();
2449263509Sdim      }
2450263509Sdim      S.Diag(MatchingMethodDecl->getLocation(), diag::note_also_found);
2451263509Sdim    }
2452263509Sdim  }
2453263509Sdim}
2454263509Sdim
2455263509Sdimvoid Sema::DiagnoseMismatchedMethodsInGlobalPool() {
2456263509Sdim  unsigned DIAG = diag::warning_multiple_selectors;
2457263509Sdim  if (Diags.getDiagnosticLevel(DIAG, SourceLocation())
2458263509Sdim      == DiagnosticsEngine::Ignored)
2459263509Sdim    return;
2460263509Sdim  for (GlobalMethodPool::iterator b = MethodPool.begin(),
2461263509Sdim       e = MethodPool.end(); b != e; b++) {
2462263509Sdim    // first, instance methods
2463263509Sdim    ObjCMethodList &InstMethList = b->second.first;
2464263509Sdim    HelperToDiagnoseMismatchedMethodsInGlobalPool(*this, InstMethList);
2465263509Sdim    // second, class methods
2466263509Sdim    ObjCMethodList &ClsMethList = b->second.second;
2467263509Sdim    HelperToDiagnoseMismatchedMethodsInGlobalPool(*this, ClsMethList);
2468263509Sdim  }
2469263509Sdim}
2470263509Sdim
2471263509Sdim/// DiagnoseDuplicateIvars -
2472204643Srdivacky/// Check for duplicate ivars in the entire class at the start of
2473245431Sdim/// \@implementation. This becomes necesssary because class extension can
2474204643Srdivacky/// add ivars to a class in random order which will not be known until
2475245431Sdim/// 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) {
2480245431Sdim    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
2494235633SdimSema::ObjCContainerKind Sema::getObjCContainerKind() const {
2495235633Sdim  switch (CurContext->getDeclKind()) {
2496235633Sdim    case Decl::ObjCInterface:
2497235633Sdim      return Sema::OCK_Interface;
2498235633Sdim    case Decl::ObjCProtocol:
2499235633Sdim      return Sema::OCK_Protocol;
2500235633Sdim    case Decl::ObjCCategory:
2501235633Sdim      if (dyn_cast<ObjCCategoryDecl>(CurContext)->IsClassExtension())
2502235633Sdim        return Sema::OCK_ClassExtension;
2503235633Sdim      else
2504235633Sdim        return Sema::OCK_Category;
2505235633Sdim    case Decl::ObjCImplementation:
2506235633Sdim      return Sema::OCK_Implementation;
2507235633Sdim    case Decl::ObjCCategoryImpl:
2508235633Sdim      return Sema::OCK_CategoryImplementation;
2509235633Sdim
2510235633Sdim    default:
2511235633Sdim      return Sema::OCK_None;
2512235633Sdim  }
2513235633Sdim}
2514235633Sdim
2515263509Sdim// Note: For class/category implementations, allMethods is always null.
2516263509SdimDecl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods,
2517263509Sdim                       ArrayRef<DeclGroupPtrTy> allTUVars) {
2518235633Sdim  if (getObjCContainerKind() == Sema::OCK_None)
2519235633Sdim    return 0;
2520235633Sdim
2521235633Sdim  assert(AtEnd.isValid() && "Invalid location for '@end'");
2522235633Sdim
2523226890Sdim  ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
2524226890Sdim  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
2535263509Sdim  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 {
2552235633Sdim        if (PrevMethod) {
2553226890Sdim          Method->setAsRedeclaration(PrevMethod);
2554235633Sdim          if (!Context.getSourceManager().isInSystemHeader(
2555235633Sdim                 Method->getLocation()))
2556235633Sdim            Diag(Method->getLocation(), diag::warn_duplicate_method_decl)
2557235633Sdim              << Method->getDeclName();
2558235633Sdim          Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
2559235633Sdim        }
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 {
2576235633Sdim        if (PrevMethod) {
2577226890Sdim          Method->setAsRedeclaration(PrevMethod);
2578235633Sdim          if (!Context.getSourceManager().isInSystemHeader(
2579235633Sdim                 Method->getLocation()))
2580235633Sdim            Diag(Method->getLocation(), diag::warn_duplicate_method_decl)
2581235633Sdim              << Method->getDeclName();
2582235633Sdim          Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
2583235633Sdim        }
2584193326Sed        ClsMap[Method->getSelector()] = Method;
2585193326Sed        AddFactoryMethodToGlobalPool(Method);
2586193326Sed      }
2587193326Sed    }
2588193326Sed  }
2589252723Sdim  if (isa<ObjCInterfaceDecl>(ClassDecl)) {
2590252723Sdim    // 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.
2620252723Sdim      for (ObjCInterfaceDecl::visible_extensions_iterator
2621252723Sdim             Ext = IDecl->visible_extensions_begin(),
2622252723Sdim             ExtEnd = IDecl->visible_extensions_end();
2623252723Sdim           Ext != ExtEnd; ++Ext) {
2624252723Sdim        for (ObjCContainerDecl::prop_iterator I = Ext->prop_begin(),
2625252723Sdim             E = Ext->prop_end(); I != E; ++I) {
2626245431Sdim          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;
2633252723Sdim
2634252723Sdim          for (ObjCInterfaceDecl::visible_extensions_iterator
2635252723Sdim                 Ext = IDecl->visible_extensions_begin(),
2636252723Sdim                 ExtEnd = IDecl->visible_extensions_end();
2637252723Sdim               Ext != ExtEnd; ++Ext) {
2638252723Sdim            if (ObjCMethodDecl *GetterMethod
2639252723Sdim                  = Ext->getInstanceMethod(Property->getGetterName()))
2640245431Sdim              GetterMethod->setPropertyAccessor(true);
2641218893Sdim            if (!Property->isReadOnly())
2642252723Sdim              if (ObjCMethodDecl *SetterMethod
2643252723Sdim                    = Ext->getInstanceMethod(Property->getSetterName()))
2644245431Sdim                SetterMethod->setPropertyAccessor(true);
2645252723Sdim          }
2646218893Sdim        }
2647218893Sdim      }
2648208600Srdivacky      ImplMethodsVsClassMethods(S, IC, IDecl);
2649199482Srdivacky      AtomicPropertySetterGetterRules(IC, IDecl);
2650224145Sdim      DiagnoseOwningPropertyGetterSynthesis(IC);
2651212904Sdim
2652235633Sdim      bool HasRootClassAttr = IDecl->hasAttr<ObjCRootClassAttr>();
2653235633Sdim      if (IDecl->getSuperClass() == NULL) {
2654235633Sdim        // This class has no superclass, so check that it has been marked with
2655235633Sdim        // __attribute((objc_root_class)).
2656235633Sdim        if (!HasRootClassAttr) {
2657235633Sdim          SourceLocation DeclLoc(IDecl->getLocation());
2658235633Sdim          SourceLocation SuperClassLoc(PP.getLocForEndOfToken(DeclLoc));
2659235633Sdim          Diag(DeclLoc, diag::warn_objc_root_class_missing)
2660235633Sdim            << IDecl->getIdentifier();
2661235633Sdim          // See if NSObject is in the current scope, and if it is, suggest
2662235633Sdim          // adding " : NSObject " to the class declaration.
2663235633Sdim          NamedDecl *IF = LookupSingleName(TUScope,
2664235633Sdim                                           NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject),
2665235633Sdim                                           DeclLoc, LookupOrdinaryName);
2666235633Sdim          ObjCInterfaceDecl *NSObjectDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
2667235633Sdim          if (NSObjectDecl && NSObjectDecl->getDefinition()) {
2668235633Sdim            Diag(SuperClassLoc, diag::note_objc_needs_superclass)
2669235633Sdim              << FixItHint::CreateInsertion(SuperClassLoc, " : NSObject ");
2670235633Sdim          } else {
2671235633Sdim            Diag(SuperClassLoc, diag::note_objc_needs_superclass);
2672235633Sdim          }
2673235633Sdim        }
2674235633Sdim      } else if (HasRootClassAttr) {
2675235633Sdim        // Complain that only root classes may have this attribute.
2676235633Sdim        Diag(IDecl->getLocation(), diag::err_objc_root_class_subclass);
2677235633Sdim      }
2678235633Sdim
2679245431Sdim      if (LangOpts.ObjCRuntime.isNonFragile()) {
2680204643Srdivacky        while (IDecl->getSuperClass()) {
2681204643Srdivacky          DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass());
2682204643Srdivacky          IDecl = IDecl->getSuperClass();
2683204643Srdivacky        }
2684235633Sdim      }
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()) {
2694252723Sdim      if (ObjCCategoryDecl *Cat
2695252723Sdim            = IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier())) {
2696252723Sdim        ImplMethodsVsClassMethods(S, CatImplClass, Cat);
2697193326Sed      }
2698193326Sed    }
2699193326Sed  }
2700193326Sed  if (isInterfaceDeclKind) {
2701193326Sed    // Reject invalid vardecls.
2702263509Sdim    for (unsigned i = 0, e = allTUVars.size(); i != e; i++) {
2703263509Sdim      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  }
2711226890Sdim  ActOnObjCContainerFinishDefinition();
2712235633Sdim
2713263509Sdim  for (unsigned i = 0, e = allTUVars.size(); i != e; i++) {
2714263509Sdim    DeclGroupRef DG = allTUVars[i].get();
2715235633Sdim    for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
2716235633Sdim      (*I)->setTopLevelDeclInObjCContainer();
2717235633Sdim    Consumer.HandleTopLevelDeclInObjCContainer(DG);
2718235633Sdim  }
2719235633Sdim
2720245431Sdim  ActOnDocumentableDecl(ClassDecl);
2721235633Sdim  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
2733245431Sdimunsigned countAlignAttr(const AttrVec &A) {
2734245431Sdim  unsigned count=0;
2735245431Sdim  for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i)
2736245431Sdim    if ((*i)->getKind() == attr::Aligned)
2737245431Sdim      ++count;
2738245431Sdim  return count;
2739245431Sdim}
2740245431Sdim
2741245431Sdimstatic inline
2742235633Sdimbool containsInvalidMethodImplAttribute(ObjCMethodDecl *IMD,
2743235633Sdim                                        const AttrVec &A) {
2744235633Sdim  // If method is only declared in implementation (private method),
2745235633Sdim  // No need to issue any diagnostics on method definition with attributes.
2746235633Sdim  if (!IMD)
2747235633Sdim    return false;
2748245431Sdim
2749235633Sdim  // method declared in interface has no attribute.
2750245431Sdim  // But implementation has attributes. This is invalid.
2751245431Sdim  // Except when implementation has 'Align' attribute which is
2752245431Sdim  // immaterial to method declared in interface.
2753235633Sdim  if (!IMD->hasAttrs())
2754245431Sdim    return (A.size() > countAlignAttr(A));
2755235633Sdim
2756235633Sdim  const AttrVec &D = IMD->getAttrs();
2757245431Sdim
2758245431Sdim  unsigned countAlignOnImpl = countAlignAttr(A);
2759245431Sdim  if (!countAlignOnImpl && (A.size() != D.size()))
2760235633Sdim    return true;
2761245431Sdim  else if (countAlignOnImpl) {
2762245431Sdim    unsigned countAlignOnDecl = countAlignAttr(D);
2763245431Sdim    if (countAlignOnDecl && (A.size() != D.size()))
2764245431Sdim      return true;
2765245431Sdim    else if (!countAlignOnDecl &&
2766245431Sdim             ((A.size()-countAlignOnImpl) != D.size()))
2767245431Sdim      return true;
2768245431Sdim  }
2769245431Sdim
2770235633Sdim  // attributes on method declaration and definition must match exactly.
2771235633Sdim  // Note that we have at most a couple of attributes on methods, so this
2772235633Sdim  // n*n search is good enough.
2773235633Sdim  for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i) {
2774245431Sdim    if ((*i)->getKind() == attr::Aligned)
2775245431Sdim      continue;
2776235633Sdim    bool match = false;
2777235633Sdim    for (AttrVec::const_iterator i1 = D.begin(), e1 = D.end(); i1 != e1; ++i1) {
2778235633Sdim      if ((*i)->getKind() == (*i1)->getKind()) {
2779235633Sdim        match = true;
2780235633Sdim        break;
2781235633Sdim      }
2782235633Sdim    }
2783235633Sdim    if (!match)
2784212904Sdim      return true;
2785235633Sdim  }
2786245431Sdim
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///
2793245431Sdimstatic 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())
2806245431Sdim      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
2812235633Sdim        if (declaresSameEntity(CurrentClass, ResultClass))
2813245431Sdim          return Sema::RTC_Compatible;
2814223017Sdim
2815223017Sdim        //   - it is a superclass of the method's class type
2816223017Sdim        if (ResultClass->isSuperClassOf(CurrentClass))
2817245431Sdim          return Sema::RTC_Compatible;
2818223017Sdim      }
2819226890Sdim    } else {
2820226890Sdim      // Any Objective-C pointer type might be acceptable for a protocol
2821226890Sdim      // method; we just don't know.
2822245431Sdim      return Sema::RTC_Unknown;
2823223017Sdim    }
2824223017Sdim  }
2825223017Sdim
2826245431Sdim  return Sema::RTC_Incompatible;
2827223017Sdim}
2828223017Sdim
2829226890Sdimnamespace {
2830226890Sdim/// A helper class for searching for methods which a particular method
2831226890Sdim/// overrides.
2832226890Sdimclass OverrideSearch {
2833235633Sdimpublic:
2834226890Sdim  Sema &S;
2835226890Sdim  ObjCMethodDecl *Method;
2836235633Sdim  llvm::SmallPtrSet<ObjCMethodDecl*, 4> Overridden;
2837226890Sdim  bool Recursive;
2838226890Sdim
2839226890Sdimpublic:
2840226890Sdim  OverrideSearch(Sema &S, ObjCMethodDecl *method) : S(S), Method(method) {
2841226890Sdim    Selector selector = method->getSelector();
2842226890Sdim
2843226890Sdim    // Bypass this search if we've never seen an instance/class method
2844226890Sdim    // with this selector before.
2845226890Sdim    Sema::GlobalMethodPool::iterator it = S.MethodPool.find(selector);
2846226890Sdim    if (it == S.MethodPool.end()) {
2847245431Sdim      if (!S.getExternalSource()) return;
2848235633Sdim      S.ReadMethodPool(selector);
2849235633Sdim
2850235633Sdim      it = S.MethodPool.find(selector);
2851235633Sdim      if (it == S.MethodPool.end())
2852235633Sdim        return;
2853226890Sdim    }
2854226890Sdim    ObjCMethodList &list =
2855226890Sdim      method->isInstanceMethod() ? it->second.first : it->second.second;
2856226890Sdim    if (!list.Method) return;
2857226890Sdim
2858226890Sdim    ObjCContainerDecl *container
2859226890Sdim      = cast<ObjCContainerDecl>(method->getDeclContext());
2860226890Sdim
2861226890Sdim    // Prevent the search from reaching this container again.  This is
2862226890Sdim    // important with categories, which override methods from the
2863226890Sdim    // interface and each other.
2864245431Sdim    if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(container)) {
2865245431Sdim      searchFromContainer(container);
2866245431Sdim      if (ObjCInterfaceDecl *Interface = Category->getClassInterface())
2867245431Sdim        searchFromContainer(Interface);
2868245431Sdim    } else {
2869245431Sdim      searchFromContainer(container);
2870245431Sdim    }
2871223017Sdim  }
2872226890Sdim
2873235633Sdim  typedef llvm::SmallPtrSet<ObjCMethodDecl*, 128>::iterator iterator;
2874226890Sdim  iterator begin() const { return Overridden.begin(); }
2875226890Sdim  iterator end() const { return Overridden.end(); }
2876226890Sdim
2877226890Sdimprivate:
2878226890Sdim  void searchFromContainer(ObjCContainerDecl *container) {
2879226890Sdim    if (container->isInvalidDecl()) return;
2880226890Sdim
2881226890Sdim    switch (container->getDeclKind()) {
2882226890Sdim#define OBJCCONTAINER(type, base) \
2883226890Sdim    case Decl::type: \
2884226890Sdim      searchFrom(cast<type##Decl>(container)); \
2885226890Sdim      break;
2886226890Sdim#define ABSTRACT_DECL(expansion)
2887226890Sdim#define DECL(type, base) \
2888226890Sdim    case Decl::type:
2889226890Sdim#include "clang/AST/DeclNodes.inc"
2890226890Sdim      llvm_unreachable("not an ObjC container!");
2891226890Sdim    }
2892226890Sdim  }
2893226890Sdim
2894226890Sdim  void searchFrom(ObjCProtocolDecl *protocol) {
2895235633Sdim    if (!protocol->hasDefinition())
2896235633Sdim      return;
2897235633Sdim
2898226890Sdim    // A method in a protocol declaration overrides declarations from
2899226890Sdim    // referenced ("parent") protocols.
2900226890Sdim    search(protocol->getReferencedProtocols());
2901226890Sdim  }
2902226890Sdim
2903226890Sdim  void searchFrom(ObjCCategoryDecl *category) {
2904226890Sdim    // A method in a category declaration overrides declarations from
2905226890Sdim    // the main class and from protocols the category references.
2906245431Sdim    // The main class is handled in the constructor.
2907226890Sdim    search(category->getReferencedProtocols());
2908226890Sdim  }
2909226890Sdim
2910226890Sdim  void searchFrom(ObjCCategoryImplDecl *impl) {
2911226890Sdim    // A method in a category definition that has a category
2912226890Sdim    // declaration overrides declarations from the category
2913226890Sdim    // declaration.
2914226890Sdim    if (ObjCCategoryDecl *category = impl->getCategoryDecl()) {
2915226890Sdim      search(category);
2916245431Sdim      if (ObjCInterfaceDecl *Interface = category->getClassInterface())
2917245431Sdim        search(Interface);
2918226890Sdim
2919226890Sdim    // Otherwise it overrides declarations from the class.
2920245431Sdim    } else if (ObjCInterfaceDecl *Interface = impl->getClassInterface()) {
2921245431Sdim      search(Interface);
2922226890Sdim    }
2923226890Sdim  }
2924226890Sdim
2925226890Sdim  void searchFrom(ObjCInterfaceDecl *iface) {
2926226890Sdim    // A method in a class declaration overrides declarations from
2927235633Sdim    if (!iface->hasDefinition())
2928235633Sdim      return;
2929235633Sdim
2930226890Sdim    //   - categories,
2931252723Sdim    for (ObjCInterfaceDecl::known_categories_iterator
2932252723Sdim           cat = iface->known_categories_begin(),
2933252723Sdim           catEnd = iface->known_categories_end();
2934252723Sdim         cat != catEnd; ++cat) {
2935252723Sdim      search(*cat);
2936252723Sdim    }
2937226890Sdim
2938226890Sdim    //   - the super class, and
2939226890Sdim    if (ObjCInterfaceDecl *super = iface->getSuperClass())
2940226890Sdim      search(super);
2941226890Sdim
2942226890Sdim    //   - any referenced protocols.
2943226890Sdim    search(iface->getReferencedProtocols());
2944226890Sdim  }
2945226890Sdim
2946226890Sdim  void searchFrom(ObjCImplementationDecl *impl) {
2947226890Sdim    // A method in a class implementation overrides declarations from
2948226890Sdim    // the class interface.
2949245431Sdim    if (ObjCInterfaceDecl *Interface = impl->getClassInterface())
2950245431Sdim      search(Interface);
2951226890Sdim  }
2952226890Sdim
2953226890Sdim
2954226890Sdim  void search(const ObjCProtocolList &protocols) {
2955226890Sdim    for (ObjCProtocolList::iterator i = protocols.begin(), e = protocols.end();
2956226890Sdim         i != e; ++i)
2957226890Sdim      search(*i);
2958226890Sdim  }
2959226890Sdim
2960226890Sdim  void search(ObjCContainerDecl *container) {
2961226890Sdim    // Check for a method in this container which matches this selector.
2962226890Sdim    ObjCMethodDecl *meth = container->getMethod(Method->getSelector(),
2963252723Sdim                                                Method->isInstanceMethod(),
2964252723Sdim                                                /*AllowHidden=*/true);
2965226890Sdim
2966226890Sdim    // If we find one, record it and bail out.
2967226890Sdim    if (meth) {
2968226890Sdim      Overridden.insert(meth);
2969226890Sdim      return;
2970226890Sdim    }
2971226890Sdim
2972226890Sdim    // Otherwise, search for methods that a hypothetical method here
2973226890Sdim    // would have overridden.
2974226890Sdim
2975226890Sdim    // Note that we're now in a recursive case.
2976226890Sdim    Recursive = true;
2977226890Sdim
2978226890Sdim    searchFromContainer(container);
2979226890Sdim  }
2980226890Sdim};
2981223017Sdim}
2982223017Sdim
2983245431Sdimvoid Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod,
2984245431Sdim                                    ObjCInterfaceDecl *CurrentClass,
2985245431Sdim                                    ResultTypeCompatibilityKind RTC) {
2986245431Sdim  // Search for overridden methods and merge information down from them.
2987245431Sdim  OverrideSearch overrides(*this, ObjCMethod);
2988245431Sdim  // Keep track if the method overrides any method in the class's base classes,
2989245431Sdim  // its protocols, or its categories' protocols; we will keep that info
2990245431Sdim  // in the ObjCMethodDecl.
2991245431Sdim  // For this info, a method in an implementation is not considered as
2992245431Sdim  // overriding the same method in the interface or its categories.
2993245431Sdim  bool hasOverriddenMethodsInBaseOrProtocol = false;
2994245431Sdim  for (OverrideSearch::iterator
2995245431Sdim         i = overrides.begin(), e = overrides.end(); i != e; ++i) {
2996245431Sdim    ObjCMethodDecl *overridden = *i;
2997245431Sdim
2998252723Sdim    if (!hasOverriddenMethodsInBaseOrProtocol) {
2999252723Sdim      if (isa<ObjCProtocolDecl>(overridden->getDeclContext()) ||
3000252723Sdim          CurrentClass != overridden->getClassInterface() ||
3001252723Sdim          overridden->isOverriding()) {
3002252723Sdim        hasOverriddenMethodsInBaseOrProtocol = true;
3003245431Sdim
3004252723Sdim      } else if (isa<ObjCImplDecl>(ObjCMethod->getDeclContext())) {
3005252723Sdim        // OverrideSearch will return as "overridden" the same method in the
3006252723Sdim        // interface. For hasOverriddenMethodsInBaseOrProtocol, we need to
3007252723Sdim        // check whether a category of a base class introduced a method with the
3008252723Sdim        // same selector, after the interface method declaration.
3009252723Sdim        // To avoid unnecessary lookups in the majority of cases, we use the
3010252723Sdim        // extra info bits in GlobalMethodPool to check whether there were any
3011252723Sdim        // category methods with this selector.
3012252723Sdim        GlobalMethodPool::iterator It =
3013252723Sdim            MethodPool.find(ObjCMethod->getSelector());
3014252723Sdim        if (It != MethodPool.end()) {
3015252723Sdim          ObjCMethodList &List =
3016252723Sdim            ObjCMethod->isInstanceMethod()? It->second.first: It->second.second;
3017252723Sdim          unsigned CategCount = List.getBits();
3018252723Sdim          if (CategCount > 0) {
3019252723Sdim            // If the method is in a category we'll do lookup if there were at
3020252723Sdim            // least 2 category methods recorded, otherwise only one will do.
3021252723Sdim            if (CategCount > 1 ||
3022252723Sdim                !isa<ObjCCategoryImplDecl>(overridden->getDeclContext())) {
3023252723Sdim              OverrideSearch overrides(*this, overridden);
3024252723Sdim              for (OverrideSearch::iterator
3025252723Sdim                     OI= overrides.begin(), OE= overrides.end(); OI!=OE; ++OI) {
3026252723Sdim                ObjCMethodDecl *SuperOverridden = *OI;
3027252723Sdim                if (isa<ObjCProtocolDecl>(SuperOverridden->getDeclContext()) ||
3028252723Sdim                    CurrentClass != SuperOverridden->getClassInterface()) {
3029252723Sdim                  hasOverriddenMethodsInBaseOrProtocol = true;
3030252723Sdim                  overridden->setOverriding(true);
3031252723Sdim                  break;
3032252723Sdim                }
3033252723Sdim              }
3034252723Sdim            }
3035252723Sdim          }
3036252723Sdim        }
3037252723Sdim      }
3038252723Sdim    }
3039252723Sdim
3040245431Sdim    // Propagate down the 'related result type' bit from overridden methods.
3041245431Sdim    if (RTC != Sema::RTC_Incompatible && overridden->hasRelatedResultType())
3042245431Sdim      ObjCMethod->SetRelatedResultType();
3043245431Sdim
3044245431Sdim    // Then merge the declarations.
3045245431Sdim    mergeObjCMethodDecls(ObjCMethod, overridden);
3046245431Sdim
3047245431Sdim    if (ObjCMethod->isImplicit() && overridden->isImplicit())
3048245431Sdim      continue; // Conflicting properties are detected elsewhere.
3049245431Sdim
3050245431Sdim    // Check for overriding methods
3051245431Sdim    if (isa<ObjCInterfaceDecl>(ObjCMethod->getDeclContext()) ||
3052245431Sdim        isa<ObjCImplementationDecl>(ObjCMethod->getDeclContext()))
3053245431Sdim      CheckConflictingOverridingMethod(ObjCMethod, overridden,
3054245431Sdim              isa<ObjCProtocolDecl>(overridden->getDeclContext()));
3055245431Sdim
3056245431Sdim    if (CurrentClass && overridden->getDeclContext() != CurrentClass &&
3057245431Sdim        isa<ObjCInterfaceDecl>(overridden->getDeclContext()) &&
3058245431Sdim        !overridden->isImplicit() /* not meant for properties */) {
3059245431Sdim      ObjCMethodDecl::param_iterator ParamI = ObjCMethod->param_begin(),
3060245431Sdim                                          E = ObjCMethod->param_end();
3061245431Sdim      ObjCMethodDecl::param_iterator PrevI = overridden->param_begin(),
3062245431Sdim                                     PrevE = overridden->param_end();
3063245431Sdim      for (; ParamI != E && PrevI != PrevE; ++ParamI, ++PrevI) {
3064245431Sdim        assert(PrevI != overridden->param_end() && "Param mismatch");
3065245431Sdim        QualType T1 = Context.getCanonicalType((*ParamI)->getType());
3066245431Sdim        QualType T2 = Context.getCanonicalType((*PrevI)->getType());
3067245431Sdim        // If type of argument of method in this class does not match its
3068245431Sdim        // respective argument type in the super class method, issue warning;
3069245431Sdim        if (!Context.typesAreCompatible(T1, T2)) {
3070245431Sdim          Diag((*ParamI)->getLocation(), diag::ext_typecheck_base_super)
3071245431Sdim            << T1 << T2;
3072245431Sdim          Diag(overridden->getLocation(), diag::note_previous_declaration);
3073245431Sdim          break;
3074245431Sdim        }
3075245431Sdim      }
3076245431Sdim    }
3077245431Sdim  }
3078245431Sdim
3079245431Sdim  ObjCMethod->setOverriding(hasOverriddenMethodsInBaseOrProtocol);
3080245431Sdim}
3081245431Sdim
3082212904SdimDecl *Sema::ActOnMethodDeclaration(
3083218893Sdim    Scope *S,
3084193326Sed    SourceLocation MethodLoc, SourceLocation EndLoc,
3085226890Sdim    tok::TokenKind MethodType,
3086212904Sdim    ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
3087226890Sdim    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.
3096226890Sdim  if (!CurContext->isObjCContainer()) {
3097193326Sed    Diag(MethodLoc, diag::error_missing_method_context);
3098212904Sdim    return 0;
3099193326Sed  }
3100226890Sdim  ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
3101226890Sdim  Decl *ClassDecl = cast<Decl>(OCD);
3102193326Sed  QualType resultDeclType;
3103198092Srdivacky
3104226890Sdim  bool HasRelatedResultType = false;
3105204962Srdivacky  TypeSourceInfo *ResultTInfo = 0;
3106193326Sed  if (ReturnType) {
3107204962Srdivacky    resultDeclType = GetTypeFromParser(ReturnType, &ResultTInfo);
3108198092Srdivacky
3109263509Sdim    if (CheckFunctionReturnType(resultDeclType, MethodLoc))
3110212904Sdim      return 0;
3111263509Sdim
3112226890Sdim    HasRelatedResultType = (resultDeclType == Context.getObjCInstanceType());
3113226890Sdim  } else { // get the type for "id".
3114193326Sed    resultDeclType = Context.getObjCIdType();
3115226890Sdim    Diag(MethodLoc, diag::warn_missing_method_return_type)
3116226890Sdim      << FixItHint::CreateInsertion(SelectorLocs.front(), "(id)");
3117226890Sdim  }
3118198092Srdivacky
3119198092Srdivacky  ObjCMethodDecl* ObjCMethod =
3120226890Sdim    ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel,
3121226890Sdim                           resultDeclType,
3122204962Srdivacky                           ResultTInfo,
3123226890Sdim                           CurContext,
3124193326Sed                           MethodType == tok::minus, isVariadic,
3125245431Sdim                           /*isPropertyAccessor=*/false,
3126226890Sdim                           /*isImplicitlyDeclared=*/false, /*isDefined=*/false,
3127223017Sdim                           MethodDeclKind == tok::objc_optional
3128223017Sdim                             ? ObjCMethodDecl::Optional
3129223017Sdim                             : ObjCMethodDecl::Required,
3130226890Sdim                           HasRelatedResultType);
3131198092Srdivacky
3132226890Sdim  SmallVector<ParmVarDecl*, 16> Params;
3133198092Srdivacky
3134193326Sed  for (unsigned i = 0, e = Sel.getNumArgs(); i != e; ++i) {
3135198893Srdivacky    QualType ArgType;
3136200583Srdivacky    TypeSourceInfo *DI;
3137198092Srdivacky
3138263509Sdim    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,
3166252723Sdim                                        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
3176235633Sdim    if (Param->hasAttr<BlocksAttr>()) {
3177235633Sdim      Diag(Param->getLocation(), diag::err_block_on_nonlocal);
3178235633Sdim      Param->setInvalidDecl();
3179235633Sdim    }
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);
3194263509Sdim
3195207619Srdivacky    Param->setDeclContext(ObjCMethod);
3196207619Srdivacky    Params.push_back(Param);
3197207619Srdivacky  }
3198207619Srdivacky
3199226890Sdim  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.
3207226890Sdim  const ObjCMethodDecl *PrevMethod = 0;
3208226890Sdim  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
3217235633Sdim    ObjCMethodDecl *IMD = 0;
3218235633Sdim    if (ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface())
3219235633Sdim      IMD = IDecl->lookupMethod(ObjCMethod->getSelector(),
3220235633Sdim                                ObjCMethod->isInstanceMethod());
3221263509Sdim    if (IMD && IMD->hasAttr<ObjCRequiresSuperAttr>() &&
3222263509Sdim        !ObjCMethod->hasAttr<ObjCRequiresSuperAttr>()) {
3223263509Sdim      // merge the attribute into implementation.
3224263509Sdim      ObjCMethod->addAttr(
3225263509Sdim        new (Context) ObjCRequiresSuperAttr(ObjCMethod->getLocation(), Context));
3226263509Sdim    }
3227212904Sdim    if (ObjCMethod->hasAttrs() &&
3228235633Sdim        containsInvalidMethodImplAttribute(IMD, ObjCMethod->getAttrs())) {
3229235633Sdim      SourceLocation MethodLoc = IMD->getLocation();
3230235633Sdim      if (!getSourceManager().isInSystemHeader(MethodLoc)) {
3231235633Sdim        Diag(EndLoc, diag::warn_attribute_method_def);
3232235633Sdim        Diag(MethodLoc, diag::note_method_declared_at)
3233235633Sdim          << ObjCMethod->getDeclName();
3234235633Sdim      }
3235235633Sdim    }
3236218893Sdim  } else {
3237218893Sdim    cast<DeclContext>(ClassDecl)->addDecl(ObjCMethod);
3238193326Sed  }
3239226890Sdim
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);
3245263509Sdim    ObjCMethod->setInvalidDecl();
3246263509Sdim    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  }
3262226890Sdim
3263226890Sdim  ResultTypeCompatibilityKind RTC
3264226890Sdim    = CheckRelatedResultTypeCompatibility(*this, ObjCMethod, CurrentClass);
3265226890Sdim
3266245431Sdim  CheckObjCMethodOverrides(ObjCMethod, CurrentClass, RTC);
3267226890Sdim
3268224145Sdim  bool ARCError = false;
3269235633Sdim  if (getLangOpts().ObjCAutoRefCount)
3270252723Sdim    ARCError = CheckARCMethodDecl(ObjCMethod);
3271224145Sdim
3272226890Sdim  // Infer the related result type when possible.
3273245431Sdim  if (!ARCError && RTC == Sema::RTC_Compatible &&
3274226890Sdim      !ObjCMethod->hasRelatedResultType() &&
3275226890Sdim      LangOpts.ObjCInferRelatedResultType) {
3276223017Sdim    bool InferRelatedResultType = false;
3277223017Sdim    switch (ObjCMethod->getMethodFamily()) {
3278223017Sdim    case OMF_None:
3279223017Sdim    case OMF_copy:
3280223017Sdim    case OMF_dealloc:
3281226890Sdim    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
3301226890Sdim    if (InferRelatedResultType)
3302223017Sdim      ObjCMethod->SetRelatedResultType();
3303223017Sdim  }
3304245431Sdim
3305245431Sdim  ActOnDocumentableDecl(ObjCMethod);
3306245431Sdim
3307212904Sdim  return ObjCMethod;
3308193326Sed}
3309193326Sed
3310193326Sedbool Sema::CheckObjCDeclScope(Decl *D) {
3311226890Sdim  // Following is also an error. But it is caused by a missing @end
3312226890Sdim  // and diagnostic is issued elsewhere.
3313235633Sdim  if (isa<ObjCContainerDecl>(CurContext->getRedeclContext()))
3314226890Sdim    return false;
3315235633Sdim
3316235633Sdim  // If we switched context to translation unit while we are still lexically in
3317235633Sdim  // an objc container, it means the parser missed emitting an error.
3318235633Sdim  if (isa<TranslationUnitDecl>(getCurLexicalContext()->getRedeclContext()))
3319235633Sdim    return false;
3320226890Sdim
3321193326Sed  Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
3322193326Sed  D->setInvalidDecl();
3323198092Srdivacky
3324193326Sed  return true;
3325193326Sed}
3326193326Sed
3327245431Sdim/// 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,
3331226890Sdim                     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  }
3338245431Sdim  if (LangOpts.ObjCRuntime.isNonFragile()) {
3339193326Sed    Diag(DeclStart, diag::err_atdef_nonfragile_interface);
3340193326Sed    return;
3341193326Sed  }
3342198092Srdivacky
3343193326Sed  // Collect the instance variables
3344226890Sdim  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++) {
3348226890Sdim    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.
3359226890Sdim  for (SmallVectorImpl<Decl*>::iterator D = Decls.begin();
3360193326Sed       D != Decls.end(); ++D) {
3361212904Sdim    FieldDecl *FD = cast<FieldDecl>(*D);
3362235633Sdim    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,
3399252723Sdim                                 T, TInfo, SC_None);
3400207619Srdivacky  New->setExceptionVariable(true);
3401207619Srdivacky
3402235633Sdim  // In ARC, infer 'retaining' for variables of retainable type.
3403235633Sdim  if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(New))
3404235633Sdim    Invalid = true;
3405235633Sdim
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()));
3419252723Sdim  } else if (DeclSpec::SCS SCS = DS.getStorageClassSpec()) {
3420207619Srdivacky    Diag(DS.getStorageClassSpecLoc(), diag::err_storage_spec_on_catch_parm)
3421252723Sdim      << DeclSpec::getSpecifierName(SCS);
3422252723Sdim  }
3423252723Sdim  if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec())
3424252723Sdim    Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
3425252723Sdim         diag::err_invalid_thread)
3426252723Sdim     << DeclSpec::getSpecifierName(TSCS);
3427207619Srdivacky  D.getMutableDeclSpec().ClearStorageClassSpecs();
3428207619Srdivacky
3429252723Sdim  DiagnoseFunctionSpecifiers(D.getDeclSpec());
3430207619Srdivacky
3431207619Srdivacky  // Check that there are no default arguments inside the type of this
3432207619Srdivacky  // exception object (C++ only).
3433235633Sdim  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,
3467226890Sdim                                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
3476226890Sdimvoid Sema::DiagnoseUseOfUnimplementedSelectors() {
3477226890Sdim  // Load referenced selectors from the external source.
3478226890Sdim  if (ExternalSource) {
3479226890Sdim    SmallVector<std::pair<Selector, SourceLocation>, 4> Sels;
3480226890Sdim    ExternalSource->ReadReferencedSelectors(Sels);
3481226890Sdim    for (unsigned I = 0, N = Sels.size(); I != N; ++I)
3482226890Sdim      ReferencedSelectors[Sels[I].first] = Sels[I].second;
3483207619Srdivacky  }
3484226890Sdim
3485263509Sdim  DiagnoseMismatchedMethodsInGlobalPool();
3486263509Sdim
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}
3502263509Sdim
3503263509SdimObjCIvarDecl *
3504263509SdimSema::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method,
3505263509Sdim                                     const ObjCPropertyDecl *&PDecl) const {
3506263509Sdim
3507263509Sdim  const ObjCInterfaceDecl *IDecl = Method->getClassInterface();
3508263509Sdim  if (!IDecl)
3509263509Sdim    return 0;
3510263509Sdim  Method = IDecl->lookupMethod(Method->getSelector(), true);
3511263509Sdim  if (!Method || !Method->isPropertyAccessor())
3512263509Sdim    return 0;
3513263509Sdim  if ((PDecl = Method->findPropertyDecl())) {
3514263509Sdim    if (!PDecl->getDeclContext())
3515263509Sdim      return 0;
3516263509Sdim    // Make sure property belongs to accessor's class and not to
3517263509Sdim    // one of its super classes.
3518263509Sdim    if (const ObjCInterfaceDecl *CID =
3519263509Sdim        dyn_cast<ObjCInterfaceDecl>(PDecl->getDeclContext()))
3520263509Sdim      if (CID != IDecl)
3521263509Sdim        return 0;
3522263509Sdim    return PDecl->getPropertyIvarDecl();
3523263509Sdim  }
3524263509Sdim  return 0;
3525263509Sdim}
3526263509Sdim
3527263509Sdimvoid Sema::DiagnoseUnusedBackingIvarInAccessor(Scope *S) {
3528263509Sdim  if (S->hasUnrecoverableErrorOccurred() || !S->isInObjcMethodScope())
3529263509Sdim    return;
3530263509Sdim
3531263509Sdim  const ObjCMethodDecl *CurMethod = getCurMethodDecl();
3532263509Sdim  if (!CurMethod)
3533263509Sdim    return;
3534263509Sdim  const ObjCPropertyDecl *PDecl;
3535263509Sdim  const ObjCIvarDecl *IV = GetIvarBackingPropertyAccessor(CurMethod, PDecl);
3536263509Sdim  if (IV && !IV->getBackingIvarReferencedInAccessor()) {
3537263509Sdim    Diag(getCurMethodDecl()->getLocation(), diag::warn_unused_property_backing_ivar)
3538263509Sdim    << IV->getDeclName();
3539263509Sdim    Diag(PDecl->getLocation(), diag::note_property_declare);
3540263509Sdim  }
3541263509Sdim}
3542