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