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