14d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner//===--- SemaDeclObjC.cpp - Semantic Analysis for ObjC Declarations -------===// 24d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner// 34d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner// The LLVM Compiler Infrastructure 44d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 74d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner// 84d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner//===----------------------------------------------------------------------===// 94d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner// 104d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner// This file implements semantic analysis for Objective C declarations. 114d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner// 124d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner//===----------------------------------------------------------------------===// 134d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 142d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h" 15f85e193739c953358c865005855253af4f68a497John McCall#include "clang/AST/ASTConsumer.h" 164d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner#include "clang/AST/ASTContext.h" 171a43415b28e60e0e421ef60e254126acec7ab462Argyrios Kyrtzidis#include "clang/AST/ASTMutationListener.h" 18651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/AST/DataRecursiveASTVisitor.h" 1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/DeclObjC.h" 2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/Expr.h" 2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/ExprObjC.h" 22f85e193739c953358c865005855253af4f68a497John McCall#include "clang/Basic/SourceManager.h" 2355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/DeclSpec.h" 2455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/ExternalSemaSource.h" 2555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/Lookup.h" 2655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/Scope.h" 2755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/ScopeInfo.h" 2850df6ae41f232612e5e88b19e0db9900d08d2f6cJohn McCall#include "llvm/ADT/DenseSet.h" 2950df6ae41f232612e5e88b19e0db9900d08d2f6cJohn McCall 304d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattnerusing namespace clang; 314d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 32f85e193739c953358c865005855253af4f68a497John McCall/// Check whether the given method, which must be in the 'init' 33f85e193739c953358c865005855253af4f68a497John McCall/// family, is a valid member of that family. 34f85e193739c953358c865005855253af4f68a497John McCall/// 35f85e193739c953358c865005855253af4f68a497John McCall/// \param receiverTypeIfCall - if null, check this as if declaring it; 36f85e193739c953358c865005855253af4f68a497John McCall/// if non-null, check this as if making a call to it with the given 37f85e193739c953358c865005855253af4f68a497John McCall/// receiver type 38f85e193739c953358c865005855253af4f68a497John McCall/// 39f85e193739c953358c865005855253af4f68a497John McCall/// \return true to indicate that there was an error and appropriate 40f85e193739c953358c865005855253af4f68a497John McCall/// actions were taken 41f85e193739c953358c865005855253af4f68a497John McCallbool Sema::checkInitMethod(ObjCMethodDecl *method, 42f85e193739c953358c865005855253af4f68a497John McCall QualType receiverTypeIfCall) { 43f85e193739c953358c865005855253af4f68a497John McCall if (method->isInvalidDecl()) return true; 44f85e193739c953358c865005855253af4f68a497John McCall 45f85e193739c953358c865005855253af4f68a497John McCall // This castAs is safe: methods that don't return an object 46f85e193739c953358c865005855253af4f68a497John McCall // pointer won't be inferred as inits and will reject an explicit 47f85e193739c953358c865005855253af4f68a497John McCall // objc_method_family(init). 48f85e193739c953358c865005855253af4f68a497John McCall 49f85e193739c953358c865005855253af4f68a497John McCall // We ignore protocols here. Should we? What about Class? 50f85e193739c953358c865005855253af4f68a497John McCall 51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ObjCObjectType *result = 52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines method->getReturnType()->castAs<ObjCObjectPointerType>()->getObjectType(); 53f85e193739c953358c865005855253af4f68a497John McCall 54f85e193739c953358c865005855253af4f68a497John McCall if (result->isObjCId()) { 55f85e193739c953358c865005855253af4f68a497John McCall return false; 56f85e193739c953358c865005855253af4f68a497John McCall } else if (result->isObjCClass()) { 57f85e193739c953358c865005855253af4f68a497John McCall // fall through: always an error 58f85e193739c953358c865005855253af4f68a497John McCall } else { 59f85e193739c953358c865005855253af4f68a497John McCall ObjCInterfaceDecl *resultClass = result->getInterface(); 60f85e193739c953358c865005855253af4f68a497John McCall assert(resultClass && "unexpected object type!"); 61f85e193739c953358c865005855253af4f68a497John McCall 62f85e193739c953358c865005855253af4f68a497John McCall // It's okay for the result type to still be a forward declaration 63f85e193739c953358c865005855253af4f68a497John McCall // if we're checking an interface declaration. 647723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor if (!resultClass->hasDefinition()) { 65f85e193739c953358c865005855253af4f68a497John McCall if (receiverTypeIfCall.isNull() && 66f85e193739c953358c865005855253af4f68a497John McCall !isa<ObjCImplementationDecl>(method->getDeclContext())) 67f85e193739c953358c865005855253af4f68a497John McCall return false; 68f85e193739c953358c865005855253af4f68a497John McCall 69f85e193739c953358c865005855253af4f68a497John McCall // Otherwise, we try to compare class types. 70f85e193739c953358c865005855253af4f68a497John McCall } else { 71f85e193739c953358c865005855253af4f68a497John McCall // If this method was declared in a protocol, we can't check 72f85e193739c953358c865005855253af4f68a497John McCall // anything unless we have a receiver type that's an interface. 736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const ObjCInterfaceDecl *receiverClass = nullptr; 74f85e193739c953358c865005855253af4f68a497John McCall if (isa<ObjCProtocolDecl>(method->getDeclContext())) { 75f85e193739c953358c865005855253af4f68a497John McCall if (receiverTypeIfCall.isNull()) 76f85e193739c953358c865005855253af4f68a497John McCall return false; 77f85e193739c953358c865005855253af4f68a497John McCall 78f85e193739c953358c865005855253af4f68a497John McCall receiverClass = receiverTypeIfCall->castAs<ObjCObjectPointerType>() 79f85e193739c953358c865005855253af4f68a497John McCall ->getInterfaceDecl(); 80f85e193739c953358c865005855253af4f68a497John McCall 81f85e193739c953358c865005855253af4f68a497John McCall // This can be null for calls to e.g. id<Foo>. 82f85e193739c953358c865005855253af4f68a497John McCall if (!receiverClass) return false; 83f85e193739c953358c865005855253af4f68a497John McCall } else { 84f85e193739c953358c865005855253af4f68a497John McCall receiverClass = method->getClassInterface(); 85f85e193739c953358c865005855253af4f68a497John McCall assert(receiverClass && "method not associated with a class!"); 86f85e193739c953358c865005855253af4f68a497John McCall } 87f85e193739c953358c865005855253af4f68a497John McCall 88f85e193739c953358c865005855253af4f68a497John McCall // If either class is a subclass of the other, it's fine. 89f85e193739c953358c865005855253af4f68a497John McCall if (receiverClass->isSuperClassOf(resultClass) || 90f85e193739c953358c865005855253af4f68a497John McCall resultClass->isSuperClassOf(receiverClass)) 91f85e193739c953358c865005855253af4f68a497John McCall return false; 92f85e193739c953358c865005855253af4f68a497John McCall } 93f85e193739c953358c865005855253af4f68a497John McCall } 94f85e193739c953358c865005855253af4f68a497John McCall 95f85e193739c953358c865005855253af4f68a497John McCall SourceLocation loc = method->getLocation(); 96f85e193739c953358c865005855253af4f68a497John McCall 97f85e193739c953358c865005855253af4f68a497John McCall // If we're in a system header, and this is not a call, just make 98f85e193739c953358c865005855253af4f68a497John McCall // the method unusable. 99f85e193739c953358c865005855253af4f68a497John McCall if (receiverTypeIfCall.isNull() && getSourceManager().isInSystemHeader(loc)) { 100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines method->addAttr(UnavailableAttr::CreateImplicit(Context, 101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "init method returns a type unrelated to its receiver type", 102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines loc)); 103f85e193739c953358c865005855253af4f68a497John McCall return true; 104f85e193739c953358c865005855253af4f68a497John McCall } 105f85e193739c953358c865005855253af4f68a497John McCall 106f85e193739c953358c865005855253af4f68a497John McCall // Otherwise, it's an error. 107f85e193739c953358c865005855253af4f68a497John McCall Diag(loc, diag::err_arc_init_method_unrelated_result_type); 108f85e193739c953358c865005855253af4f68a497John McCall method->setInvalidDecl(); 109f85e193739c953358c865005855253af4f68a497John McCall return true; 110f85e193739c953358c865005855253af4f68a497John McCall} 111f85e193739c953358c865005855253af4f68a497John McCall 1123240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanianvoid Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, 113f4d918fdf7da64215db8abe63945798c66e6d132Douglas Gregor const ObjCMethodDecl *Overridden) { 114926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (Overridden->hasRelatedResultType() && 115926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor !NewMethod->hasRelatedResultType()) { 116926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // This can only happen when the method follows a naming convention that 117926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // implies a related result type, and the original (overridden) method has 118926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // a suitable return type, but the new (overriding) method does not have 119926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // a suitable return type. 120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType ResultType = NewMethod->getReturnType(); 121176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines SourceRange ResultTypeRange = NewMethod->getReturnTypeSourceRange(); 122926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 123926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // Figure out which class this method is part of, if any. 124926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor ObjCInterfaceDecl *CurrentClass 125926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor = dyn_cast<ObjCInterfaceDecl>(NewMethod->getDeclContext()); 126926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (!CurrentClass) { 127926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor DeclContext *DC = NewMethod->getDeclContext(); 128926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(DC)) 129926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor CurrentClass = Cat->getClassInterface(); 130926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor else if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(DC)) 131926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor CurrentClass = Impl->getClassInterface(); 132926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor else if (ObjCCategoryImplDecl *CatImpl 133926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor = dyn_cast<ObjCCategoryImplDecl>(DC)) 134926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor CurrentClass = CatImpl->getClassInterface(); 135926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 136926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 137926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (CurrentClass) { 138926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor Diag(NewMethod->getLocation(), 139926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor diag::warn_related_result_type_compatibility_class) 140926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor << Context.getObjCInterfaceType(CurrentClass) 141926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor << ResultType 142926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor << ResultTypeRange; 143926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } else { 144926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor Diag(NewMethod->getLocation(), 145926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor diag::warn_related_result_type_compatibility_protocol) 146926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor << ResultType 147926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor << ResultTypeRange; 148926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 149926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 150e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor if (ObjCMethodFamily Family = Overridden->getMethodFamily()) 151e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor Diag(Overridden->getLocation(), 1527cca821e1acf0f1b4fe892c3111bfb2086832e4eJohn McCall diag::note_related_result_type_family) 1537cca821e1acf0f1b4fe892c3111bfb2086832e4eJohn McCall << /*overridden method*/ 0 154e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor << Family; 155e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor else 156e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor Diag(Overridden->getLocation(), 157e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor diag::note_related_result_type_overridden); 158926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 1594e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjCAutoRefCount) { 1603240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian if ((NewMethod->hasAttr<NSReturnsRetainedAttr>() != 1613240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian Overridden->hasAttr<NSReturnsRetainedAttr>())) { 1623240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian Diag(NewMethod->getLocation(), 1633240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian diag::err_nsreturns_retained_attribute_mismatch) << 1; 1643240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian Diag(Overridden->getLocation(), diag::note_previous_decl) 1653240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian << "method"; 1663240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian } 1673240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian if ((NewMethod->hasAttr<NSReturnsNotRetainedAttr>() != 1683240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian Overridden->hasAttr<NSReturnsNotRetainedAttr>())) { 1693240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian Diag(NewMethod->getLocation(), 1703240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian diag::err_nsreturns_retained_attribute_mismatch) << 0; 1713240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian Diag(Overridden->getLocation(), diag::note_previous_decl) 1723240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian << "method"; 1733240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian } 1740a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor ObjCMethodDecl::param_const_iterator oi = Overridden->param_begin(), 1750a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor oe = Overridden->param_end(); 176491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis for (ObjCMethodDecl::param_iterator 177491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis ni = NewMethod->param_begin(), ne = NewMethod->param_end(); 1780a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor ni != ne && oi != oe; ++ni, ++oi) { 179491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis const ParmVarDecl *oldDecl = (*oi); 1803240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian ParmVarDecl *newDecl = (*ni); 1813240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian if (newDecl->hasAttr<NSConsumedAttr>() != 1823240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian oldDecl->hasAttr<NSConsumedAttr>()) { 1833240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian Diag(newDecl->getLocation(), 1843240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian diag::err_nsconsumed_attribute_mismatch); 1853240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian Diag(oldDecl->getLocation(), diag::note_previous_decl) 1863240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian << "parameter"; 1873240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian } 1883240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian } 1893240fe3b715327c8fda6f5a3bc8a092b1fce82a7Fariborz Jahanian } 190926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor} 191926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 192f85e193739c953358c865005855253af4f68a497John McCall/// \brief Check a method declaration for compatibility with the Objective-C 193f85e193739c953358c865005855253af4f68a497John McCall/// ARC conventions. 194b846381fc3099b2340ba8c74d16178203a60d9a0John McCallbool Sema::CheckARCMethodDecl(ObjCMethodDecl *method) { 195f85e193739c953358c865005855253af4f68a497John McCall ObjCMethodFamily family = method->getMethodFamily(); 196f85e193739c953358c865005855253af4f68a497John McCall switch (family) { 197f85e193739c953358c865005855253af4f68a497John McCall case OMF_None: 19880cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber case OMF_finalize: 199f85e193739c953358c865005855253af4f68a497John McCall case OMF_retain: 200f85e193739c953358c865005855253af4f68a497John McCall case OMF_release: 201f85e193739c953358c865005855253af4f68a497John McCall case OMF_autorelease: 202f85e193739c953358c865005855253af4f68a497John McCall case OMF_retainCount: 203f85e193739c953358c865005855253af4f68a497John McCall case OMF_self: 204176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case OMF_initialize: 2056c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall case OMF_performSelector: 206f85e193739c953358c865005855253af4f68a497John McCall return false; 207f85e193739c953358c865005855253af4f68a497John McCall 2081b0a13e91088f6818016464ffb23616ced820cbcFariborz Jahanian case OMF_dealloc: 209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!Context.hasSameType(method->getReturnType(), Context.VoidTy)) { 210176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines SourceRange ResultTypeRange = method->getReturnTypeSourceRange(); 2111b0a13e91088f6818016464ffb23616ced820cbcFariborz Jahanian if (ResultTypeRange.isInvalid()) 212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diag(method->getLocation(), diag::error_dealloc_bad_result_type) 213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << method->getReturnType() 214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << FixItHint::CreateInsertion(method->getSelectorLoc(0), "(void)"); 2151b0a13e91088f6818016464ffb23616ced820cbcFariborz Jahanian else 216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diag(method->getLocation(), diag::error_dealloc_bad_result_type) 217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << method->getReturnType() 218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << FixItHint::CreateReplacement(ResultTypeRange, "void"); 2191b0a13e91088f6818016464ffb23616ced820cbcFariborz Jahanian return true; 2201b0a13e91088f6818016464ffb23616ced820cbcFariborz Jahanian } 2211b0a13e91088f6818016464ffb23616ced820cbcFariborz Jahanian return false; 2221b0a13e91088f6818016464ffb23616ced820cbcFariborz Jahanian 223f85e193739c953358c865005855253af4f68a497John McCall case OMF_init: 224f85e193739c953358c865005855253af4f68a497John McCall // If the method doesn't obey the init rules, don't bother annotating it. 225b846381fc3099b2340ba8c74d16178203a60d9a0John McCall if (checkInitMethod(method, QualType())) 226f85e193739c953358c865005855253af4f68a497John McCall return true; 227f85e193739c953358c865005855253af4f68a497John McCall 228651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines method->addAttr(NSConsumesSelfAttr::CreateImplicit(Context)); 229f85e193739c953358c865005855253af4f68a497John McCall 230f85e193739c953358c865005855253af4f68a497John McCall // Don't add a second copy of this attribute, but otherwise don't 231f85e193739c953358c865005855253af4f68a497John McCall // let it be suppressed. 232f85e193739c953358c865005855253af4f68a497John McCall if (method->hasAttr<NSReturnsRetainedAttr>()) 233f85e193739c953358c865005855253af4f68a497John McCall return false; 234f85e193739c953358c865005855253af4f68a497John McCall break; 235f85e193739c953358c865005855253af4f68a497John McCall 236f85e193739c953358c865005855253af4f68a497John McCall case OMF_alloc: 237f85e193739c953358c865005855253af4f68a497John McCall case OMF_copy: 238f85e193739c953358c865005855253af4f68a497John McCall case OMF_mutableCopy: 239f85e193739c953358c865005855253af4f68a497John McCall case OMF_new: 240f85e193739c953358c865005855253af4f68a497John McCall if (method->hasAttr<NSReturnsRetainedAttr>() || 241f85e193739c953358c865005855253af4f68a497John McCall method->hasAttr<NSReturnsNotRetainedAttr>() || 242f85e193739c953358c865005855253af4f68a497John McCall method->hasAttr<NSReturnsAutoreleasedAttr>()) 243f85e193739c953358c865005855253af4f68a497John McCall return false; 244f85e193739c953358c865005855253af4f68a497John McCall break; 245f85e193739c953358c865005855253af4f68a497John McCall } 246f85e193739c953358c865005855253af4f68a497John McCall 247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines method->addAttr(NSReturnsRetainedAttr::CreateImplicit(Context)); 248f85e193739c953358c865005855253af4f68a497John McCall return false; 249f85e193739c953358c865005855253af4f68a497John McCall} 250f85e193739c953358c865005855253af4f68a497John McCall 2515ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanianstatic void DiagnoseObjCImplementedDeprecations(Sema &S, 2525ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian NamedDecl *ND, 2535ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian SourceLocation ImplLoc, 2545ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian int select) { 2550a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (ND && ND->isDeprecated()) { 25698d810ee83d4c4bf5d89bbb43829533b84b20ecfFariborz Jahanian S.Diag(ImplLoc, diag::warn_deprecated_def) << select; 2575ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian if (select == 0) 2583306ec1923973d7b5767b23ba95915af2fec87d7Ted Kremenek S.Diag(ND->getLocation(), diag::note_method_declared_at) 2593306ec1923973d7b5767b23ba95915af2fec87d7Ted Kremenek << ND->getDeclName(); 2605ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian else 2615ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian S.Diag(ND->getLocation(), diag::note_previous_decl) << "class"; 2625ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian } 2635ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian} 2645ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian 265140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian/// AddAnyMethodToGlobalPool - Add any method, instance or factory to global 266140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian/// pool. 267140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanianvoid Sema::AddAnyMethodToGlobalPool(Decl *D) { 268140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D); 269140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian 270140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian // If we don't have a valid method decl, simply return. 271140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian if (!MDecl) 272140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian return; 273140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian if (MDecl->isInstanceMethod()) 274140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian AddInstanceMethodToGlobalPool(MDecl, true); 275140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian else 276140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian AddFactoryMethodToGlobalPool(MDecl, true); 277140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian} 278140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian 279a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian/// HasExplicitOwnershipAttr - returns true when pointer to ObjC pointer 280a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian/// has explicit ownership attribute; false otherwise. 281a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanianstatic bool 282a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz JahanianHasExplicitOwnershipAttr(Sema &S, ParmVarDecl *Param) { 283a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian QualType T = Param->getType(); 284a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian 285a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian if (const PointerType *PT = T->getAs<PointerType>()) { 286a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian T = PT->getPointeeType(); 287a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian } else if (const ReferenceType *RT = T->getAs<ReferenceType>()) { 288a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian T = RT->getPointeeType(); 289a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian } else { 290a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian return true; 291a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian } 292a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian 293a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian // If we have a lifetime qualifier, but it's local, we must have 294a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian // inferred it. So, it is implicit. 295a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian return !T.getLocalQualifiers().hasObjCLifetime(); 296a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian} 297a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian 2988c6cb462946b8be19167fad7ff21d4f9fbaebfefFariborz Jahanian/// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible 2998c6cb462946b8be19167fad7ff21d4f9fbaebfefFariborz Jahanian/// and user declared, in the method definition's AST. 3008c6cb462946b8be19167fad7ff21d4f9fbaebfefFariborz Jahanianvoid Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { 3016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert((getCurMethodDecl() == nullptr) && "Methodparsing confused"); 302d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D); 3036c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian 304394f3f483fa4e7b472630cfcd03f7840520958c5Steve Naroff // If we don't have a valid method decl, simply return. 305394f3f483fa4e7b472630cfcd03f7840520958c5Steve Naroff if (!MDecl) 306394f3f483fa4e7b472630cfcd03f7840520958c5Steve Naroff return; 307a56f616744b929aa7115034e7e2f9a0b8df545f6Steve Naroff 3084d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Allow all of Sema to see that we are entering a method definition. 30944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor PushDeclContext(FnBodyScope, MDecl); 3109ea9bdbc14374f7bacdb50d3e52c664ff12150ffDouglas Gregor PushFunctionScope(); 3119ea9bdbc14374f7bacdb50d3e52c664ff12150ffDouglas Gregor 3124d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Create Decl objects for each parameter, entrring them in the scope for 3134d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // binding to their use. 3144d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 3154d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Insert the invisible arguments, self and _cmd! 316fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanian MDecl->createImplicitParams(Context, MDecl->getClassInterface()); 3171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 318451318c08a6342c10b8986060386fd9274418437Daniel Dunbar PushOnScopeChains(MDecl->getSelfDecl(), FnBodyScope); 319451318c08a6342c10b8986060386fd9274418437Daniel Dunbar PushOnScopeChains(MDecl->getCmdDecl(), FnBodyScope); 32004421087832a031c90bd58f128c7c0e741db8dd2Chris Lattner 3218c0501c7370d894a735692b92fab62bbb05d86bdReid Kleckner // The ObjC parser requires parameter names so there's no need to check. 3228c0501c7370d894a735692b92fab62bbb05d86bdReid Kleckner CheckParmsForFunctionDef(MDecl->param_begin(), MDecl->param_end(), 3238c0501c7370d894a735692b92fab62bbb05d86bdReid Kleckner /*CheckParameterNames=*/false); 3248c0501c7370d894a735692b92fab62bbb05d86bdReid Kleckner 3258123a95c33b792d35c2e4992ba6e27882748fb0dChris Lattner // Introduce all of the other parameters into this scope. 326651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *Param : MDecl->params()) { 32723c0104bb8ad04f06804bd399cbc1f5f962b356cFariborz Jahanian if (!Param->isInvalidDecl() && 328a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian getLangOpts().ObjCAutoRefCount && 329a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian !HasExplicitOwnershipAttr(*this, Param)) 330a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian Diag(Param->getLocation(), diag::warn_arc_strong_pointer_objc_pointer) << 331a1a32f7f5966edf47c1e22bcbeb2a09bc462ff0bFariborz Jahanian Param->getType(); 332918546c584c91ee917c919c967d7d73cecd295dcFariborz Jahanian 333651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Param->getIdentifier()) 334651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PushOnScopeChains(Param, FnBodyScope); 33523c0104bb8ad04f06804bd399cbc1f5f962b356cFariborz Jahanian } 336f85e193739c953358c865005855253af4f68a497John McCall 337f85e193739c953358c865005855253af4f68a497John McCall // In ARC, disallow definition of retain/release/autorelease/retainCount 3384e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjCAutoRefCount) { 339f85e193739c953358c865005855253af4f68a497John McCall switch (MDecl->getMethodFamily()) { 340f85e193739c953358c865005855253af4f68a497John McCall case OMF_retain: 341f85e193739c953358c865005855253af4f68a497John McCall case OMF_retainCount: 342f85e193739c953358c865005855253af4f68a497John McCall case OMF_release: 343f85e193739c953358c865005855253af4f68a497John McCall case OMF_autorelease: 344f85e193739c953358c865005855253af4f68a497John McCall Diag(MDecl->getLocation(), diag::err_arc_illegal_method_def) 345b8ed071b88c1fd100eaa701f5fd7f5ebe8b9e362Fariborz Jahanian << 0 << MDecl->getSelector(); 346f85e193739c953358c865005855253af4f68a497John McCall break; 347f85e193739c953358c865005855253af4f68a497John McCall 348f85e193739c953358c865005855253af4f68a497John McCall case OMF_None: 349f85e193739c953358c865005855253af4f68a497John McCall case OMF_dealloc: 35080cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber case OMF_finalize: 351f85e193739c953358c865005855253af4f68a497John McCall case OMF_alloc: 352f85e193739c953358c865005855253af4f68a497John McCall case OMF_init: 353f85e193739c953358c865005855253af4f68a497John McCall case OMF_mutableCopy: 354f85e193739c953358c865005855253af4f68a497John McCall case OMF_copy: 355f85e193739c953358c865005855253af4f68a497John McCall case OMF_new: 356f85e193739c953358c865005855253af4f68a497John McCall case OMF_self: 357176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case OMF_initialize: 3589670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian case OMF_performSelector: 359f85e193739c953358c865005855253af4f68a497John McCall break; 360f85e193739c953358c865005855253af4f68a497John McCall } 361f85e193739c953358c865005855253af4f68a497John McCall } 362f85e193739c953358c865005855253af4f68a497John McCall 3639a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber // Warn on deprecated methods under -Wdeprecated-implementations, 3649a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber // and prepare for warning on missing super calls. 3659a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber if (ObjCInterfaceDecl *IC = MDecl->getClassInterface()) { 366841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian ObjCMethodDecl *IMD = 367841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian IC->lookupMethod(MDecl->getSelector(), MDecl->isInstanceMethod()); 368841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian 3695fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian if (IMD) { 3705fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian ObjCImplDecl *ImplDeclOfMethodDef = 3715fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian dyn_cast<ObjCImplDecl>(MDecl->getDeclContext()); 3725fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian ObjCContainerDecl *ContDeclOfMethodDecl = 3735fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian dyn_cast<ObjCContainerDecl>(IMD->getDeclContext()); 3746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ObjCImplDecl *ImplDeclOfMethodDecl = nullptr; 3755fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ContDeclOfMethodDecl)) 3765fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian ImplDeclOfMethodDecl = OID->getImplementation(); 377651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(ContDeclOfMethodDecl)) { 378651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CD->IsClassExtension()) { 379651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (ObjCInterfaceDecl *OID = CD->getClassInterface()) 380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ImplDeclOfMethodDecl = OID->getImplementation(); 381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else 382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ImplDeclOfMethodDecl = CD->getImplementation(); 383651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 3845fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian // No need to issue deprecated warning if deprecated mehod in class/category 3855fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian // is being implemented in its own implementation (no overriding is involved). 3865fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian if (!ImplDeclOfMethodDecl || ImplDeclOfMethodDecl != ImplDeclOfMethodDef) 3875fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian DiagnoseObjCImplementedDeprecations(*this, 3885ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian dyn_cast<NamedDecl>(IMD), 3895ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian MDecl->getLocation(), 0); 3905fa667612e0466982407ae678cdfeb68b878ed65Fariborz Jahanian } 3919a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber 392651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (MDecl->getMethodFamily() == OMF_init) { 393651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (MDecl->isDesignatedInitializerForTheInterface()) { 394651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getCurFunction()->ObjCIsDesignatedInit = true; 395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getCurFunction()->ObjCWarnForNoDesignatedInitChain = 3966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines IC->getSuperClass() != nullptr; 397651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (IC->hasDesignatedInitializers()) { 398651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getCurFunction()->ObjCIsSecondaryInit = true; 399651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getCurFunction()->ObjCWarnForNoInitDelegation = true; 400651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 401651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 402651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 40380cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber // If this is "dealloc" or "finalize", set some bit here. 4049a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber // Then in ActOnSuperMessage() (SemaExprObjC), set it back to false. 4059a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber // Finally, in ActOnFinishFunctionBody() (SemaDecl), warn if flag is set. 4069a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber // Only do this if the current class actually has a superclass. 40741f3f3a4792f46787632fdb94f952f6b3ce3f4aeJordan Rose if (const ObjCInterfaceDecl *SuperClass = IC->getSuperClass()) { 408535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose ObjCMethodFamily Family = MDecl->getMethodFamily(); 409535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose if (Family == OMF_dealloc) { 410535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose if (!(getLangOpts().ObjCAutoRefCount || 411535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose getLangOpts().getGC() == LangOptions::GCOnly)) 412535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose getCurFunction()->ObjCShouldCallSuper = true; 413535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose 414535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose } else if (Family == OMF_finalize) { 415535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose if (Context.getLangOpts().getGC() != LangOptions::NonGC) 416535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose getCurFunction()->ObjCShouldCallSuper = true; 417535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose 4182b61039ceb9162e7b47ed4cb92b957c8a7668da1Fariborz Jahanian } else { 419535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose const ObjCMethodDecl *SuperMethod = 42041f3f3a4792f46787632fdb94f952f6b3ce3f4aeJordan Rose SuperClass->lookupMethod(MDecl->getSelector(), 42141f3f3a4792f46787632fdb94f952f6b3ce3f4aeJordan Rose MDecl->isInstanceMethod()); 422535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose getCurFunction()->ObjCShouldCallSuper = 423535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose (SuperMethod && SuperMethod->hasAttr<ObjCRequiresSuperAttr>()); 4246f9386049c6dee2df33a4b7a6dfeda2733acce7dFariborz Jahanian } 42580cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber } 4269a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber } 4274d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 4284d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 4292f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrainnamespace { 4302f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain 4312f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain// Callback to only accept typo corrections that are Objective-C classes. 4322f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain// If an ObjCInterfaceDecl* is given to the constructor, then the validation 4332f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain// function will reject corrections to that class. 4342f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrainclass ObjCInterfaceValidatorCCC : public CorrectionCandidateCallback { 4352f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain public: 4366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ObjCInterfaceValidatorCCC() : CurrentIDecl(nullptr) {} 4372f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain explicit ObjCInterfaceValidatorCCC(ObjCInterfaceDecl *IDecl) 4382f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain : CurrentIDecl(IDecl) {} 4392f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain 440651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool ValidateCandidate(const TypoCorrection &candidate) override { 4412f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain ObjCInterfaceDecl *ID = candidate.getCorrectionDeclAs<ObjCInterfaceDecl>(); 4422f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain return ID && !declaresSameEntity(ID, CurrentIDecl); 4432f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain } 4442f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain 4452f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain private: 4462f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain ObjCInterfaceDecl *CurrentIDecl; 4472f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain}; 4482f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain 4492f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain} 4502f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain 451d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema:: 4527caeabd868d46cf4e68478c6e9136dae4e735d21Chris LattnerActOnStartClassInterface(SourceLocation AtInterfaceLoc, 4537caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner IdentifierInfo *ClassName, SourceLocation ClassLoc, 4547caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner IdentifierInfo *SuperName, SourceLocation SuperLoc, 455d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl * const *ProtoRefs, unsigned NumProtoRefs, 45618df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor const SourceLocation *ProtoLocs, 4577caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner SourceLocation EndProtoLoc, AttributeList *AttrList) { 4584d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner assert(ClassName && "Missing class identifier"); 4591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4604d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check for another declaration kind with the same name. 461c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, ClassLoc, 462c0b39640de335809ca7544f802751112619f30ccDouglas Gregor LookupOrdinaryName, ForRedeclaration); 46372c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor 464a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) { 4653c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName; 4665f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(PrevDecl->getLocation(), diag::note_previous_definition); 4674d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 4681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4697723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor // Create a declaration to describe this @interface. 4700af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl); 471e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis 472e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) { 473e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // A previous decl with a different name is because of 474e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // @compatibility_alias, for example: 475e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // \code 476e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // @class NewImage; 477e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // @compatibility_alias OldImage NewImage; 478e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // \endcode 479e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // A lookup for 'OldImage' will return the 'NewImage' decl. 480e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // 481e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // In such a case use the real declaration name, instead of the alias one, 482e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // otherwise we will break IdentifierResolver and redecls-chain invariants. 483e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // FIXME: If necessary, add a bit to indicate that this ObjCInterfaceDecl 484e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // has been aliased. 485e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis ClassName = PrevIDecl->getIdentifier(); 486e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis } 487e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis 4887723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor ObjCInterfaceDecl *IDecl 4897723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName, 4900af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor PrevIDecl, ClassLoc); 4917723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor 4927723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor if (PrevIDecl) { 4937723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor // Class already seen. Was it a definition? 4947723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) { 4957723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor Diag(AtInterfaceLoc, diag::err_duplicate_class_def) 4967723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor << PrevIDecl->getDeclName(); 4972e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor Diag(Def->getLocation(), diag::note_previous_definition); 4987723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor IDecl->setInvalidDecl(); 4994d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 500deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor } 5017723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor 5027723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor if (AttrList) 5037723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor ProcessDeclAttributeList(TUScope, IDecl, AttrList); 5047723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor PushOnScopeChains(IDecl, TUScope); 50574c730ad1f6818b676b0bad46d806a9176950328Sebastian Redl 5067723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor // Start the definition of this class. If we're in a redefinition case, there 5077723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor // may already be a definition, so we'll end up adding to it. 5082e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor if (!IDecl->hasDefinition()) 5092e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor IDecl->startDefinition(); 5102e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor 5114d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (SuperName) { 5124d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check if a different kind of symbol declared in this scope. 513c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor PrevDecl = LookupSingleName(TUScope, SuperName, SuperLoc, 514c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor LookupOrdinaryName); 515f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor 516f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor if (!PrevDecl) { 5172f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain // Try to correct for a typo in the superclass name without correcting 5182f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain // to the class we're defining. 519176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (TypoCorrection Corrected = 520176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CorrectTypo(DeclarationNameInfo(SuperName, SuperLoc), 521176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines LookupOrdinaryName, TUScope, nullptr, 522176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::make_unique<ObjCInterfaceValidatorCCC>(IDecl), 523176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CTK_ErrorRecovery)) { 5242d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest) 5252d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith << SuperName << ClassName); 5262f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain PrevDecl = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>(); 527f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor } 528f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor } 529f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor 53060ef308e51c71b760d7f598c1b763ceb7b768148Douglas Gregor if (declaresSameEntity(PrevDecl, IDecl)) { 531fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian Diag(SuperLoc, diag::err_recursive_superclass) 532fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc); 53305c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor IDecl->setEndOfDefinitionLoc(ClassLoc); 534ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 5351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCInterfaceDecl *SuperClassDecl = 536fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl); 5373c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner 538fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian // Diagnose classes that inherit from deprecated classes. 539fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian if (SuperClassDecl) 540fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian (void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc); 5411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (PrevDecl && !SuperClassDecl) { 543fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian // The previous declaration was not a class decl. Check if we have a 544fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian // typedef. If we do, get the underlying class type. 545162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (const TypedefNameDecl *TDecl = 546162e1c1b487352434552147967c3dd296ebee2f7Richard Smith dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) { 547fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian QualType T = TDecl->getUnderlyingType(); 548c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall if (T->isObjCObjectType()) { 549740991bdf8bb2638ff111ae2084791c52c1cee00Fariborz Jahanian if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface()) { 550deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl); 551740991bdf8bb2638ff111ae2084791c52c1cee00Fariborz Jahanian // This handles the following case: 552740991bdf8bb2638ff111ae2084791c52c1cee00Fariborz Jahanian // @interface NewI @end 553740991bdf8bb2638ff111ae2084791c52c1cee00Fariborz Jahanian // typedef NewI DeprI __attribute__((deprecated("blah"))) 554740991bdf8bb2638ff111ae2084791c52c1cee00Fariborz Jahanian // @interface SI : DeprI /* warn here */ @end 555740991bdf8bb2638ff111ae2084791c52c1cee00Fariborz Jahanian (void)DiagnoseUseOfDecl(const_cast<TypedefNameDecl*>(TDecl), SuperLoc); 556740991bdf8bb2638ff111ae2084791c52c1cee00Fariborz Jahanian } 557fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian } 558818cb9eaba6279675af8c3b87c464d21d3796682Steve Naroff } 5591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 560fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian // This handles the following case: 561fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian // 562fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian // typedef int SuperClass; 563fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian // @interface MyClass : SuperClass {} @end 564fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian // 565fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian if (!SuperClassDecl) { 566fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName; 567fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian Diag(PrevDecl->getLocation(), diag::note_previous_definition); 568fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian } 569818cb9eaba6279675af8c3b87c464d21d3796682Steve Naroff } 5701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 571162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (!dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) { 572fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian if (!SuperClassDecl) 573fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian Diag(SuperLoc, diag::err_undef_superclass) 574fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc); 575b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor else if (RequireCompleteType(SuperLoc, 576d10099e5c8238fa0327f03921cf2e3c8975c881eDouglas Gregor Context.getObjCInterfaceType(SuperClassDecl), 577d10099e5c8238fa0327f03921cf2e3c8975c881eDouglas Gregor diag::err_forward_superclass, 578d10099e5c8238fa0327f03921cf2e3c8975c881eDouglas Gregor SuperClassDecl->getDeclName(), 579d10099e5c8238fa0327f03921cf2e3c8975c881eDouglas Gregor ClassName, 580d10099e5c8238fa0327f03921cf2e3c8975c881eDouglas Gregor SourceRange(AtInterfaceLoc, ClassLoc))) { 5816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SuperClassDecl = nullptr; 582a81397323cc8475ef8243f938118a9c231fb18ffFariborz Jahanian } 583fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian } 584fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian IDecl->setSuperClass(SuperClassDecl); 585fdee089b11e0bb57aa2c7291dd5e4201c2f906ffFariborz Jahanian IDecl->setSuperClassLoc(SuperLoc); 58605c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor IDecl->setEndOfDefinitionLoc(SuperLoc); 587818cb9eaba6279675af8c3b87c464d21d3796682Steve Naroff } 5884d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } else { // we have a root class. 58905c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor IDecl->setEndOfDefinitionLoc(ClassLoc); 5904d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 5911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5920b17c61e8f143901ce11b4a6e5129ac63aaeee04Sebastian Redl // Check then save referenced protocols. 59306036d3709955a53297b4cbe14e20db88f321470Chris Lattner if (NumProtoRefs) { 59431ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky IDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs, 59518df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor ProtoLocs, Context); 59605c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor IDecl->setEndOfDefinitionLoc(EndProtoLoc); 5974d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 5981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 59915281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson CheckObjCDeclScope(IDecl); 6003a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis return ActOnObjCContainerStartDefinition(IDecl); 6014d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 6024d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 603a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian/// ActOnTypedefedProtocols - this action finds protocol list as part of the 604a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian/// typedef'ed use for a qualified super class and adds them to the list 605a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian/// of the protocols. 606a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanianvoid Sema::ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs, 607a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian IdentifierInfo *SuperName, 608a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian SourceLocation SuperLoc) { 609a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian if (!SuperName) 610a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian return; 611a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian NamedDecl* IDecl = LookupSingleName(TUScope, SuperName, SuperLoc, 612a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian LookupOrdinaryName); 613a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian if (!IDecl) 614a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian return; 615a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian 616a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian if (const TypedefNameDecl *TDecl = dyn_cast_or_null<TypedefNameDecl>(IDecl)) { 617a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian QualType T = TDecl->getUnderlyingType(); 618a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian if (T->isObjCObjectType()) 619a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian if (const ObjCObjectType *OPT = T->getAs<ObjCObjectType>()) 6200e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ProtocolRefs.append(OPT->qual_begin(), OPT->qual_end()); 621a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian } 622a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian} 623a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian 624de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith/// ActOnCompatibilityAlias - this action is called after complete parsing of 6251dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// a \@compatibility_alias declaration. It sets up the alias relationships. 626de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard SmithDecl *Sema::ActOnCompatibilityAlias(SourceLocation AtLoc, 627de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith IdentifierInfo *AliasName, 628de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith SourceLocation AliasLocation, 629de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith IdentifierInfo *ClassName, 630de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith SourceLocation ClassLocation) { 6314d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Look for previous declaration of alias name 632c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, AliasLocation, 633c0b39640de335809ca7544f802751112619f30ccDouglas Gregor LookupOrdinaryName, ForRedeclaration); 6344d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (ADecl) { 635104f96ba1a59026d6a71b4ef39ca127b56324e4aEli Friedman Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName; 6368b265bd5eba1394273693e6705a43adac6b6aa2fChris Lattner Diag(ADecl->getLocation(), diag::note_previous_declaration); 6376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 6384d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 6394d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check for class declaration 640c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation, 641c0b39640de335809ca7544f802751112619f30ccDouglas Gregor LookupOrdinaryName, ForRedeclaration); 642162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (const TypedefNameDecl *TDecl = 643162e1c1b487352434552147967c3dd296ebee2f7Richard Smith dyn_cast_or_null<TypedefNameDecl>(CDeclU)) { 644305c658ebce84bb9833fc0e7675554656453b8e8Fariborz Jahanian QualType T = TDecl->getUnderlyingType(); 645c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall if (T->isObjCObjectType()) { 646c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface()) { 647305c658ebce84bb9833fc0e7675554656453b8e8Fariborz Jahanian ClassName = IDecl->getIdentifier(); 648c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation, 649c0b39640de335809ca7544f802751112619f30ccDouglas Gregor LookupOrdinaryName, ForRedeclaration); 650305c658ebce84bb9833fc0e7675554656453b8e8Fariborz Jahanian } 651305c658ebce84bb9833fc0e7675554656453b8e8Fariborz Jahanian } 652305c658ebce84bb9833fc0e7675554656453b8e8Fariborz Jahanian } 653f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner ObjCInterfaceDecl *CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDeclU); 6546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!CDecl) { 6553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(ClassLocation, diag::warn_undef_interface) << ClassName; 656f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner if (CDeclU) 6578b265bd5eba1394273693e6705a43adac6b6aa2fChris Lattner Diag(CDeclU->getLocation(), diag::note_previous_declaration); 6586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 6594d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 6601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 661f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner // Everything checked out, instantiate a new alias declaration AST. 6621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCCompatibleAliasDecl *AliasDecl = 663d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor ObjCCompatibleAliasDecl::Create(Context, CurContext, AtLoc, AliasName, CDecl); 6641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 66515281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson if (!CheckObjCDeclScope(AliasDecl)) 666516ff43cc4e20b637335d3dfa5b197ca8faa09cbDouglas Gregor PushOnScopeChains(AliasDecl, TUScope); 667d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor 668d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return AliasDecl; 6694d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 6704d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 671819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanianbool Sema::CheckForwardProtocolDeclarationForCircularDependency( 67261d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff IdentifierInfo *PName, 67361d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff SourceLocation &Ploc, SourceLocation PrevLoc, 674819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian const ObjCList<ObjCProtocolDecl> &PList) { 675819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian 676819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian bool res = false; 67761d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff for (ObjCList<ObjCProtocolDecl>::iterator I = PList.begin(), 67861d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff E = PList.end(); I != E; ++I) { 679c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor if (ObjCProtocolDecl *PDecl = LookupProtocol((*I)->getIdentifier(), 680c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor Ploc)) { 68161d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff if (PDecl->getIdentifier() == PName) { 68261d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff Diag(Ploc, diag::err_protocol_has_circular_dependency); 68361d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff Diag(PrevLoc, diag::note_previous_definition); 684819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian res = true; 68561d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff } 6865e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor 6875e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor if (!PDecl->hasDefinition()) 6885e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor continue; 6895e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor 690819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian if (CheckForwardProtocolDeclarationForCircularDependency(PName, Ploc, 691819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian PDecl->getLocation(), PDecl->getReferencedProtocols())) 692819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian res = true; 69361d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff } 69461d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff } 695819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian return res; 69661d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff} 69761d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff 698d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl * 699e13b9595dc1e2f4288bec34f3412359f648e84a5Chris LattnerSema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc, 700e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner IdentifierInfo *ProtocolName, 701e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner SourceLocation ProtocolLoc, 702d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl * const *ProtoRefs, 703e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner unsigned NumProtoRefs, 70418df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor const SourceLocation *ProtoLocs, 705246e70f69cb8aeb67225c54690f1c6b25abd5a86Daniel Dunbar SourceLocation EndProtoLoc, 706246e70f69cb8aeb67225c54690f1c6b25abd5a86Daniel Dunbar AttributeList *AttrList) { 70796b69a7305e20c98f1a3e2e7cd52e2d6c5d53835Fariborz Jahanian bool err = false; 708246e70f69cb8aeb67225c54690f1c6b25abd5a86Daniel Dunbar // FIXME: Deal with AttrList. 7094d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner assert(ProtocolName && "Missing protocol identifier"); 71027c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor ObjCProtocolDecl *PrevDecl = LookupProtocol(ProtocolName, ProtocolLoc, 71127c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor ForRedeclaration); 7126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ObjCProtocolDecl *PDecl = nullptr; 7136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (ObjCProtocolDecl *Def = PrevDecl? PrevDecl->getDefinition() : nullptr) { 71427c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // If we already have a definition, complain. 71527c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName; 71627c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor Diag(Def->getLocation(), diag::note_previous_definition); 71727c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 71827c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // Create a new protocol that is completely distinct from previous 71927c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // declarations, and do not make this protocol available for name lookup. 72027c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // That way, we'll end up completely ignoring the duplicate. 72127c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // FIXME: Can we turn this into an error? 72227c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName, 72327c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor ProtocolLoc, AtProtoInterfaceLoc, 7246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /*PrevDecl=*/nullptr); 72527c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor PDecl->startDefinition(); 72627c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor } else { 72727c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor if (PrevDecl) { 72827c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // Check for circular dependencies among protocol declarations. This can 72927c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // only happen if this protocol was forward-declared. 7304fc04da71ed46d63dc991dbea4fd52341e56c0a1Argyrios Kyrtzidis ObjCList<ObjCProtocolDecl> PList; 7314fc04da71ed46d63dc991dbea4fd52341e56c0a1Argyrios Kyrtzidis PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context); 7324fc04da71ed46d63dc991dbea4fd52341e56c0a1Argyrios Kyrtzidis err = CheckForwardProtocolDeclarationForCircularDependency( 73327c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor ProtocolName, ProtocolLoc, PrevDecl->getLocation(), PList); 7344d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 73527c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 73627c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // Create the new declaration. 7371711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName, 738b05d7b20171bbd2feb14b059f39332cbe1bf1014Argyrios Kyrtzidis ProtocolLoc, AtProtoInterfaceLoc, 739c9d3c7edb513e9b8a6ab65b04133653e71d7a72bDouglas Gregor /*PrevDecl=*/PrevDecl); 74027c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 7416e378de1aebdfeb44f2a7677ed207b32b3a41fbfDouglas Gregor PushOnScopeChains(PDecl, TUScope); 7425e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor PDecl->startDefinition(); 743cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner } 7445e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor 745bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian if (AttrList) 7469cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(TUScope, PDecl, AttrList); 74727c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 74827c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // Merge attributes from previous declarations. 74927c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor if (PrevDecl) 75027c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor mergeDeclAttributes(PDecl, PrevDecl); 75127c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 75296b69a7305e20c98f1a3e2e7cd52e2d6c5d53835Fariborz Jahanian if (!err && NumProtoRefs ) { 753c858105d41602a2dadb2efbc1af80a7b791ebac3Chris Lattner /// Check then save referenced protocols. 75431ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky PDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs, 75518df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor ProtoLocs, Context); 7564d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 7571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump CheckObjCDeclScope(PDecl); 7593a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis return ActOnObjCContainerStartDefinition(PDecl); 7604d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 7614d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 762651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic bool NestedProtocolHasNoDefinition(ObjCProtocolDecl *PDecl, 763651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCProtocolDecl *&UndefinedProtocol) { 764651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!PDecl->hasDefinition() || PDecl->getDefinition()->isHidden()) { 765651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines UndefinedProtocol = PDecl; 766651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 767651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 768651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 769651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *PI : PDecl->protocols()) 770651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (NestedProtocolHasNoDefinition(PI, UndefinedProtocol)) { 771651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines UndefinedProtocol = PI; 772651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 773651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 774651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 775651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 776651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 7774d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// FindProtocolDeclaration - This routine looks up protocols and 7787ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar/// issues an error if they are not declared. It returns list of 7797ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar/// protocol declarations in its 'Protocols' argument. 7804d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattnervoid 781e13b9595dc1e2f4288bec34f3412359f648e84a5Chris LattnerSema::FindProtocolDeclaration(bool WarnOnDeclarations, 7827caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner const IdentifierLocPair *ProtocolId, 7834d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner unsigned NumProtocols, 7845f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<Decl *> &Protocols) { 7854d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner for (unsigned i = 0; i != NumProtocols; ++i) { 786c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolId[i].first, 787c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor ProtocolId[i].second); 788eacc39212e5960b2680067c006384c2e4804873aChris Lattner if (!PDecl) { 789d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor TypoCorrection Corrected = CorrectTypo( 790d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor DeclarationNameInfo(ProtocolId[i].first, ProtocolId[i].second), 791176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines LookupObjCProtocolName, TUScope, nullptr, 792176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::make_unique<DeclFilterCCC<ObjCProtocolDecl>>(), 7936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CTK_ErrorRecovery); 7942d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith if ((PDecl = Corrected.getCorrectionDeclAs<ObjCProtocolDecl>())) 7952d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith diagnoseTypo(Corrected, PDiag(diag::err_undeclared_protocol_suggest) 7962d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith << ProtocolId[i].first); 797f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor } 798f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor 799f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor if (!PDecl) { 800fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner Diag(ProtocolId[i].second, diag::err_undeclared_protocol) 8013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << ProtocolId[i].first; 802eacc39212e5960b2680067c006384c2e4804873aChris Lattner continue; 803eacc39212e5960b2680067c006384c2e4804873aChris Lattner } 8043c9a0240b6db6ee02a24f48c753089bda48843aeFariborz Jahanian // If this is a forward protocol declaration, get its definition. 8053c9a0240b6db6ee02a24f48c753089bda48843aeFariborz Jahanian if (!PDecl->isThisDeclarationADefinition() && PDecl->getDefinition()) 8063c9a0240b6db6ee02a24f48c753089bda48843aeFariborz Jahanian PDecl = PDecl->getDefinition(); 8073c9a0240b6db6ee02a24f48c753089bda48843aeFariborz Jahanian 80848f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor (void)DiagnoseUseOfDecl(PDecl, ProtocolId[i].second); 809eacc39212e5960b2680067c006384c2e4804873aChris Lattner 810eacc39212e5960b2680067c006384c2e4804873aChris Lattner // If this is a forward declaration and we are supposed to warn in this 811eacc39212e5960b2680067c006384c2e4804873aChris Lattner // case, do it. 8120f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor // FIXME: Recover nicely in the hidden case. 813651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCProtocolDecl *UndefinedProtocol; 814651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 8150f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor if (WarnOnDeclarations && 816651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NestedProtocolHasNoDefinition(PDecl, UndefinedProtocol)) { 817fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner Diag(ProtocolId[i].second, diag::warn_undef_protocolref) 8183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << ProtocolId[i].first; 819651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diag(UndefinedProtocol->getLocation(), diag::note_protocol_decl_undefined) 820651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << UndefinedProtocol; 821651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 822d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Protocols.push_back(PDecl); 8234d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 8244d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 8254d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 82678c39c76103a36e37a05b1e40da93850ea64647bFariborz Jahanian/// DiagnoseClassExtensionDupMethods - Check for duplicate declaration of 827b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian/// a class method in its extension. 828b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian/// 8291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, 830b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian ObjCInterfaceDecl *ID) { 831b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian if (!ID) 832b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian return; // Possibly due to previous error 833b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian 834b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian llvm::DenseMap<Selector, const ObjCMethodDecl*> MethodMap; 835651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *MD : ID->methods()) 836b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian MethodMap[MD->getSelector()] = MD; 837b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian 838b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian if (MethodMap.empty()) 839b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian return; 840651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *Method : CAT->methods()) { 841b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian const ObjCMethodDecl *&PrevMethod = MethodMap[Method->getSelector()]; 842651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (PrevMethod && 843651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (PrevMethod->isInstanceMethod() == Method->isInstanceMethod()) && 844651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines !MatchTwoMethodDeclarations(Method, PrevMethod)) { 845b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian Diag(Method->getLocation(), diag::err_duplicate_method_decl) 846b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian << Method->getDeclName(); 847b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian Diag(PrevMethod->getLocation(), diag::note_previous_declaration); 848b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian } 849b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian } 850b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian} 851b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian 8521dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// ActOnForwardProtocolDeclaration - Handle \@protocol foo; 853bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas GregorSema::DeclGroupPtrTy 8544d3914836e85258e9ace7306999413e3c7ea6c11Chris LattnerSema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, 8557caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner const IdentifierLocPair *IdentList, 856bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian unsigned NumElts, 857bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian AttributeList *attrList) { 858bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor SmallVector<Decl *, 8> DeclsInGroup; 8594d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner for (unsigned i = 0; i != NumElts; ++i) { 8607caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner IdentifierInfo *Ident = IdentList[i].first; 86127c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor ObjCProtocolDecl *PrevDecl = LookupProtocol(Ident, IdentList[i].second, 86227c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor ForRedeclaration); 86327c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor ObjCProtocolDecl *PDecl 86427c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor = ObjCProtocolDecl::Create(Context, CurContext, Ident, 86527c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor IdentList[i].second, AtProtocolLoc, 866c9d3c7edb513e9b8a6ab65b04133653e71d7a72bDouglas Gregor PrevDecl); 86727c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 86827c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor PushOnScopeChains(PDecl, TUScope); 869bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor CheckObjCDeclScope(PDecl); 87027c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 8713937f87e53b3ee0c8da93536f48f6f96c006309dDouglas Gregor if (attrList) 8729cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(TUScope, PDecl, attrList); 87327c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 87427c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor if (PrevDecl) 87527c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor mergeDeclAttributes(PDecl, PrevDecl); 87627c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 877bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor DeclsInGroup.push_back(PDecl); 8784d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 8791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8804549d7ffc15bdd7ab860aa68db089d9f559b79e7Rafael Espindola return BuildDeclaratorGroup(DeclsInGroup, false); 8814d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 8824d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 883d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema:: 8847caeabd868d46cf4e68478c6e9136dae4e735d21Chris LattnerActOnStartCategoryInterface(SourceLocation AtInterfaceLoc, 8857caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner IdentifierInfo *ClassName, SourceLocation ClassLoc, 8867caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner IdentifierInfo *CategoryName, 8877caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner SourceLocation CategoryLoc, 888d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl * const *ProtoRefs, 8897caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner unsigned NumProtoRefs, 89018df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor const SourceLocation *ProtoLocs, 8917caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner SourceLocation EndProtoLoc) { 89280aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian ObjCCategoryDecl *CDecl; 893c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true); 89409b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek 89509b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek /// Check that class of this category is already completely declared. 896b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor 897b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor if (!IDecl 898b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor || RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), 899d10099e5c8238fa0327f03921cf2e3c8975c881eDouglas Gregor diag::err_category_forward_interface, 9006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CategoryName == nullptr)) { 90109b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek // Create an invalid ObjCCategoryDecl to serve as context for 90209b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek // the enclosing method declarations. We mark the decl invalid 90309b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek // to make it clear that this isn't a valid AST. 90409b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, 905955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis ClassLoc, CategoryLoc, CategoryName,IDecl); 90609b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek CDecl->setInvalidDecl(); 9079a0b6b4e2bf6a9ef41d32b4e83f2911981d2d44dArgyrios Kyrtzidis CurContext->addDecl(CDecl); 908b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor 909b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor if (!IDecl) 910b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor Diag(ClassLoc, diag::err_undef_interface) << ClassName; 9113a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis return ActOnObjCContainerStartDefinition(CDecl); 91209b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek } 91309b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek 91480aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian if (!CategoryName && IDecl->getImplementation()) { 91580aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian Diag(ClassLoc, diag::err_class_extension_after_impl) << ClassName; 91680aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian Diag(IDecl->getImplementation()->getLocation(), 91780aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian diag::note_implementation_declared); 91809b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek } 91909b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek 92025760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian if (CategoryName) { 92125760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian /// Check for duplicate interface declaration for this category 922d329724745b49f894b768d47275b7c2713106e89Douglas Gregor if (ObjCCategoryDecl *Previous 923d329724745b49f894b768d47275b7c2713106e89Douglas Gregor = IDecl->FindCategoryDeclaration(CategoryName)) { 924d329724745b49f894b768d47275b7c2713106e89Douglas Gregor // Class extensions can be declared multiple times, categories cannot. 925d329724745b49f894b768d47275b7c2713106e89Douglas Gregor Diag(CategoryLoc, diag::warn_dup_category_def) 926d329724745b49f894b768d47275b7c2713106e89Douglas Gregor << ClassName << CategoryName; 927d329724745b49f894b768d47275b7c2713106e89Douglas Gregor Diag(Previous->getLocation(), diag::note_previous_definition); 9284d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 9297c453b3ded5dc9bff05e6e66eb725a0938303d73Fariborz Jahanian } 9304d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 931955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, 932955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis ClassLoc, CategoryLoc, CategoryName, IDecl); 933955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis // FIXME: PushOnScopeChains? 934955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis CurContext->addDecl(CDecl); 935955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis 9364d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (NumProtoRefs) { 93731ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky CDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs, 93818df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor ProtoLocs, Context); 939339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian // Protocols in the class extension belong to the class. 94025760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian if (CDecl->IsClassExtension()) 94131ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky IDecl->mergeClassExtensionProtocolList((ObjCProtocolDecl*const*)ProtoRefs, 94253b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek NumProtoRefs, Context); 9434d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 9441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 94515281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson CheckObjCDeclScope(CDecl); 9463a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis return ActOnObjCContainerStartDefinition(CDecl); 9474d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 9484d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 9494d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// ActOnStartCategoryImplementation - Perform semantic checks on the 950a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// category implementation declaration and build an ObjCCategoryImplDecl 9514d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// object. 952d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema::ActOnStartCategoryImplementation( 9534d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner SourceLocation AtCatImplLoc, 9544d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner IdentifierInfo *ClassName, SourceLocation ClassLoc, 9554d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner IdentifierInfo *CatName, SourceLocation CatLoc) { 956c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true); 9576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ObjCCategoryDecl *CatIDecl = nullptr; 9585a61e0c4229dc82617a37a68ac2fc08d46e00488Argyrios Kyrtzidis if (IDecl && IDecl->hasDefinition()) { 9598a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis CatIDecl = IDecl->FindCategoryDeclaration(CatName); 9608a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis if (!CatIDecl) { 9618a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis // Category @implementation with no corresponding @interface. 9628a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis // Create and install one. 96337f40572c4c78a8c57a7b45266f8b86db172a7c1Argyrios Kyrtzidis CatIDecl = ObjCCategoryDecl::Create(Context, CurContext, AtCatImplLoc, 96437f40572c4c78a8c57a7b45266f8b86db172a7c1Argyrios Kyrtzidis ClassLoc, CatLoc, 965955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis CatName, IDecl); 96637f40572c4c78a8c57a7b45266f8b86db172a7c1Argyrios Kyrtzidis CatIDecl->setImplicit(); 9678a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis } 9688a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis } 9698a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis 9701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCCategoryImplDecl *CDecl = 9711711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis ObjCCategoryImplDecl::Create(Context, CurContext, CatName, IDecl, 972c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis ClassLoc, AtCatImplLoc, CatLoc); 9734d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner /// Check that class of this category is already completely declared. 974b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor if (!IDecl) { 9753c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(ClassLoc, diag::err_undef_interface) << ClassName; 9766c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall CDecl->setInvalidDecl(); 977b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor } else if (RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), 978b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor diag::err_undef_interface)) { 979b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor CDecl->setInvalidDecl(); 9806c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 9814d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 982d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor // FIXME: PushOnScopeChains? 98317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis CurContext->addDecl(CDecl); 984d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor 985c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis // If the interface is deprecated/unavailable, warn/error about it. 986c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis if (IDecl) 987c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis DiagnoseUseOfDecl(IDecl, ClassLoc); 988c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis 9898a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis /// Check that CatName, category name, is not used in another implementation. 9908a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis if (CatIDecl) { 9918a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis if (CatIDecl->getImplementation()) { 9928a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis Diag(ClassLoc, diag::err_dup_implementation_category) << ClassName 9938a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis << CatName; 9948a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis Diag(CatIDecl->getImplementation()->getLocation(), 9958a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis diag::note_previous_definition); 996df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis CDecl->setInvalidDecl(); 997b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian } else { 9988a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis CatIDecl->setImplementation(CDecl); 999b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian // Warn on implementating category of deprecated class under 1000b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian // -Wdeprecated-implementations flag. 10015ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian DiagnoseObjCImplementedDeprecations(*this, 10025ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian dyn_cast<NamedDecl>(IDecl), 10035ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian CDecl->getLocation(), 2); 1004b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian } 10058a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis } 10061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 100715281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson CheckObjCDeclScope(CDecl); 10083a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis return ActOnObjCContainerStartDefinition(CDecl); 10094d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 10104d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 1011d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema::ActOnStartClassImplementation( 10124d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner SourceLocation AtClassImplLoc, 10134d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner IdentifierInfo *ClassName, SourceLocation ClassLoc, 10141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump IdentifierInfo *SuperClassname, 10154d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner SourceLocation SuperClassLoc) { 10166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ObjCInterfaceDecl *IDecl = nullptr; 10174d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check for another declaration kind with the same name. 1018f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *PrevDecl 1019c0b39640de335809ca7544f802751112619f30ccDouglas Gregor = LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName, 1020c0b39640de335809ca7544f802751112619f30ccDouglas Gregor ForRedeclaration); 1021a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) { 10223c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName; 10235f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(PrevDecl->getLocation(), diag::note_previous_definition); 1024deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor } else if ((IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))) { 10250af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), 10260af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor diag::warn_undef_interface); 102795ff742380d1c3dd5152739183bfe085cf27197fDouglas Gregor } else { 10282d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith // We did not find anything with the name ClassName; try to correct for 102995ff742380d1c3dd5152739183bfe085cf27197fDouglas Gregor // typos in the class name. 1030176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TypoCorrection Corrected = CorrectTypo( 1031176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines DeclarationNameInfo(ClassName, ClassLoc), LookupOrdinaryName, TUScope, 1032176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines nullptr, llvm::make_unique<ObjCInterfaceValidatorCCC>(), CTK_NonError); 10332d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith if (Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) { 10342d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith // Suggest the (potentially) correct interface name. Don't provide a 10352d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith // code-modification hint or use the typo name for recovery, because 10362d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith // this is just a warning. The program may actually be correct. 10372d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith diagnoseTypo(Corrected, 10382d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith PDiag(diag::warn_undef_interface_suggest) << ClassName, 10392d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith /*ErrorRecovery*/false); 104095ff742380d1c3dd5152739183bfe085cf27197fDouglas Gregor } else { 104195ff742380d1c3dd5152739183bfe085cf27197fDouglas Gregor Diag(ClassLoc, diag::warn_undef_interface) << ClassName; 104295ff742380d1c3dd5152739183bfe085cf27197fDouglas Gregor } 10434d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 10441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10454d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check that super class name is valid class name 10466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ObjCInterfaceDecl *SDecl = nullptr; 10474d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (SuperClassname) { 10484d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check if a different kind of symbol declared in this scope. 1049c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor PrevDecl = LookupSingleName(TUScope, SuperClassname, SuperClassLoc, 1050c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor LookupOrdinaryName); 1051a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) { 10523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(SuperClassLoc, diag::err_redefinition_different_kind) 10533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << SuperClassname; 10545f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(PrevDecl->getLocation(), diag::note_previous_definition); 10553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner } else { 10561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump SDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl); 1057cd707abbc758149d9f7d37bd0b25298455c678b2Argyrios Kyrtzidis if (SDecl && !SDecl->hasDefinition()) 10586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SDecl = nullptr; 10594d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (!SDecl) 10603c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(SuperClassLoc, diag::err_undef_superclass) 10613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << SuperClassname << ClassName; 106260ef308e51c71b760d7f598c1b763ceb7b768148Douglas Gregor else if (IDecl && !declaresSameEntity(IDecl->getSuperClass(), SDecl)) { 10634d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // This implementation and its interface do not have the same 10644d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // super class. 10653c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(SuperClassLoc, diag::err_conflicting_super_class) 106608631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << SDecl->getDeclName(); 10675f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(SDecl->getLocation(), diag::note_previous_definition); 10684d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 10694d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 10704d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 10711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10724d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (!IDecl) { 10734d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Legacy case of @implementation with no corresponding @interface. 10744d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Build, chain & install the interface decl into the identifier. 1075f6414927e67e27d9324d8d179c5f7ea620443924Daniel Dunbar 1076390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Do we support attributes on the @implementation? If so we should 1077390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // copy them over. 10781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc, 10796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ClassName, /*PrevDecl=*/nullptr, ClassLoc, 10800af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor true); 10812e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor IDecl->startDefinition(); 108205c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor if (SDecl) { 108305c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor IDecl->setSuperClass(SDecl); 108405c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor IDecl->setSuperClassLoc(SuperClassLoc); 108505c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor IDecl->setEndOfDefinitionLoc(SuperClassLoc); 108605c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor } else { 108705c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor IDecl->setEndOfDefinitionLoc(ClassLoc); 108805c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor } 108905c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor 10908b9fb3082bc54cf7ffe6c3772500a73388f53072Douglas Gregor PushOnScopeChains(IDecl, TUScope); 1091deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor } else { 1092deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor // Mark the interface as being completed, even if it was just as 1093deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor // @class ....; 1094deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor // declaration; the user cannot reopen it. 10952e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor if (!IDecl->hasDefinition()) 10962e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor IDecl->startDefinition(); 10974d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 10981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCImplementationDecl* IMPDecl = 11001711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis ObjCImplementationDecl::Create(Context, CurContext, IDecl, SDecl, 1101634c5634817b9ad384a706fe87ab302985566bbaArgyrios Kyrtzidis ClassLoc, AtClassImplLoc, SuperClassLoc); 11021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 110315281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson if (CheckObjCDeclScope(IMPDecl)) 11043a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis return ActOnObjCContainerStartDefinition(IMPDecl); 11051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11064d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check that there is no duplicate implementation of this class. 1107deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor if (IDecl->getImplementation()) { 1108deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor // FIXME: Don't leak everything! 11093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName; 111087018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis Diag(IDecl->getImplementation()->getLocation(), 111187018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis diag::note_previous_definition); 1112df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis IMPDecl->setInvalidDecl(); 1113deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor } else { // add it to the list. 11148a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis IDecl->setImplementation(IMPDecl); 11158fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor PushOnScopeChains(IMPDecl, TUScope); 1116b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian // Warn on implementating deprecated class under 1117b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian // -Wdeprecated-implementations flag. 11185ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian DiagnoseObjCImplementedDeprecations(*this, 11195ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian dyn_cast<NamedDecl>(IDecl), 11205ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian IMPDecl->getLocation(), 1); 11218a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis } 11223a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis return ActOnObjCContainerStartDefinition(IMPDecl); 11234d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 11244d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 1125644af7b50bd0541468b45c197f5b637e934d48a0Argyrios KyrtzidisSema::DeclGroupPtrTy 1126644af7b50bd0541468b45c197f5b637e934d48a0Argyrios KyrtzidisSema::ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef<Decl *> Decls) { 1127644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis SmallVector<Decl *, 64> DeclsInGroup; 1128644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis DeclsInGroup.reserve(Decls.size() + 1); 1129644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis 1130644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis for (unsigned i = 0, e = Decls.size(); i != e; ++i) { 1131644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis Decl *Dcl = Decls[i]; 1132644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis if (!Dcl) 1133644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis continue; 1134644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis if (Dcl->getDeclContext()->isFileContext()) 1135644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis Dcl->setTopLevelDeclInObjCContainer(); 1136644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis DeclsInGroup.push_back(Dcl); 1137644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis } 1138644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis 1139644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis DeclsInGroup.push_back(ObjCImpDecl); 1140644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis 11414549d7ffc15bdd7ab860aa68db089d9f559b79e7Rafael Espindola return BuildDeclaratorGroup(DeclsInGroup, false); 1142644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis} 1143644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis 1144a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekvoid Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, 1145a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek ObjCIvarDecl **ivars, unsigned numIvars, 11464d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner SourceLocation RBrace) { 11474d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner assert(ImpDecl && "missing implementation decl"); 11484afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor ObjCInterfaceDecl* IDecl = ImpDecl->getClassInterface(); 11494d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (!IDecl) 11504d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner return; 11511dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett /// Check case of non-existing \@interface decl. 11521dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett /// (legacy objective-c \@implementation decl without an \@interface decl). 11534d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner /// Add implementations's ivar to the synthesize class's ivar list. 115433feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff if (IDecl->isImplicitInterfaceDecl()) { 115505c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor IDecl->setEndOfDefinitionLoc(RBrace); 11563a21cd92f425680fcbfbab9552c0787b09ae9ca7Fariborz Jahanian // Add ivar's to class's DeclContext. 11573a21cd92f425680fcbfbab9552c0787b09ae9ca7Fariborz Jahanian for (unsigned i = 0, e = numIvars; i != e; ++i) { 11582f14c4d18fcba4b4577dbe43016d6d42ef9973cfFariborz Jahanian ivars[i]->setLexicalDeclContext(ImpDecl); 11591b7f9cbed1b96b58a6e5f7808ebc9345a76a0936Richard Smith IDecl->makeDeclVisibleInContext(ivars[i]); 116011062e11236b7bc689dad150e8b490fd6b063ec3Fariborz Jahanian ImpDecl->addDecl(ivars[i]); 11613a21cd92f425680fcbfbab9552c0787b09ae9ca7Fariborz Jahanian } 11623a21cd92f425680fcbfbab9552c0787b09ae9ca7Fariborz Jahanian 11634d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner return; 11644d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 11654d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // If implementation has empty ivar list, just return. 11664d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (numIvars == 0) 11674d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner return; 11681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11694d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner assert(ivars && "missing @implementation ivars"); 1170260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (LangOpts.ObjCRuntime.isNonFragile()) { 1171bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian if (ImpDecl->getSuperClass()) 1172bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian Diag(ImpDecl->getLocation(), diag::warn_on_superclass_use); 1173bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian for (unsigned i = 0; i < numIvars; i++) { 1174bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian ObjCIvarDecl* ImplIvar = ivars[i]; 1175bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian if (const ObjCIvarDecl *ClsIvar = 1176bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian IDecl->getIvarDecl(ImplIvar->getIdentifier())) { 1177bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration); 1178bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian Diag(ClsIvar->getLocation(), diag::note_previous_definition); 1179bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian continue; 1180bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian } 11813b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian // Check class extensions (unnamed categories) for duplicate ivars. 1182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *CDecl : IDecl->visible_extensions()) { 11833b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian if (const ObjCIvarDecl *ClsExtIvar = 11843b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian CDecl->getIvarDecl(ImplIvar->getIdentifier())) { 11853b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration); 11863b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian Diag(ClsExtIvar->getLocation(), diag::note_previous_definition); 11873b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian continue; 11883b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian } 11893b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian } 1190bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian // Instance ivar to Implementation's DeclContext. 1191bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian ImplIvar->setLexicalDeclContext(ImpDecl); 11921b7f9cbed1b96b58a6e5f7808ebc9345a76a0936Richard Smith IDecl->makeDeclVisibleInContext(ImplIvar); 1193bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian ImpDecl->addDecl(ImplIvar); 1194bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian } 1195bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian return; 1196bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian } 11974d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check interface's Ivar list against those in the implementation. 11984d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // names and types must match. 11994d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // 12004d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner unsigned j = 0; 12011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCInterfaceDecl::ivar_iterator 12024c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner IVI = IDecl->ivar_begin(), IVE = IDecl->ivar_end(); 12034c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner for (; numIvars > 0 && IVI != IVE; ++IVI) { 1204a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek ObjCIvarDecl* ImplIvar = ivars[j++]; 1205581deb3da481053c4993c7600f97acf7768caac5David Blaikie ObjCIvarDecl* ClsIvar = *IVI; 12064d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner assert (ImplIvar && "missing implementation ivar"); 12074d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner assert (ClsIvar && "missing class ivar"); 12081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1209ca33129bb28b05938c3e6c9f8a66165b5cceb4ddSteve Naroff // First, make sure the types match. 1210a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith if (!Context.hasSameType(ImplIvar->getType(), ClsIvar->getType())) { 1211fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type) 121208631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << ImplIvar->getIdentifier() 121308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << ImplIvar->getType() << ClsIvar->getType(); 12145f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(ClsIvar->getLocation(), diag::note_previous_definition); 1215a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith } else if (ImplIvar->isBitField() && ClsIvar->isBitField() && 1216a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith ImplIvar->getBitWidthValue(Context) != 1217a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith ClsIvar->getBitWidthValue(Context)) { 1218a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith Diag(ImplIvar->getBitWidth()->getLocStart(), 1219a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith diag::err_conflicting_ivar_bitwidth) << ImplIvar->getIdentifier(); 1220a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith Diag(ClsIvar->getBitWidth()->getLocStart(), 1221a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith diag::note_previous_definition); 12221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 1223ca33129bb28b05938c3e6c9f8a66165b5cceb4ddSteve Naroff // Make sure the names are identical. 1224ca33129bb28b05938c3e6c9f8a66165b5cceb4ddSteve Naroff if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) { 1225fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name) 122608631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << ImplIvar->getIdentifier() << ClsIvar->getIdentifier(); 12275f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(ClsIvar->getLocation(), diag::note_previous_definition); 12284d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 12294d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner --numIvars; 12304d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 12311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1232609e4c72d9190a57636836d658b3563d9a9545aeChris Lattner if (numIvars > 0) 1233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diag(ivars[j]->getLocation(), diag::err_inconsistent_ivar_count); 1234609e4c72d9190a57636836d658b3563d9a9545aeChris Lattner else if (IVI != IVE) 1235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diag(IVI->getLocation(), diag::err_inconsistent_ivar_count); 12364d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 12374d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 1238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void WarnUndefinedMethod(Sema &S, SourceLocation ImpLoc, 1239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCMethodDecl *method, 1240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool &IncompleteImpl, 1241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned DiagID, 12426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines NamedDecl *NeededFor = nullptr) { 1243327126ee3d2faad9314b2633974eefc672f73b79Fariborz Jahanian // No point warning no definition of method which is 'unavailable'. 124486f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor switch (method->getAvailability()) { 124586f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor case AR_Available: 124686f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor case AR_Deprecated: 124786f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor break; 124886f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor 124986f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor // Don't warn about unavailable or not-yet-introduced methods. 125086f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor case AR_NotYetIntroduced: 125186f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor case AR_Unavailable: 1252327126ee3d2faad9314b2633974eefc672f73b79Fariborz Jahanian return; 125386f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor } 125486f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor 12558b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek // FIXME: For now ignore 'IncompleteImpl'. 12568b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek // Previously we grouped all unimplemented methods under a single 12578b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek // warning, but some users strongly voiced that they would prefer 12588b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek // separate warnings. We will give that approach a try, as that 12598b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek // matches what we do with protocols. 1260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines { 1261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Sema::SemaDiagnosticBuilder &B = S.Diag(ImpLoc, DiagID); 1262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B << method; 1263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (NeededFor) 1264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B << NeededFor; 1265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 12668b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek 12678b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek // Issue a note to the original declaration. 12688b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek SourceLocation MethodLoc = method->getLocStart(); 12698b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek if (MethodLoc.isValid()) 1270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.Diag(MethodLoc, diag::note_method_declared_at) << method; 12713c2eb66b0acb13c4bdd628e5e148c37958a85ec4Steve Naroff} 12723c2eb66b0acb13c4bdd628e5e148c37958a85ec4Steve Naroff 1273e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// Determines if type B can be substituted for type A. Returns true if we can 1274e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// guarantee that anything that the user will do to an object of type A can 1275e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// also be done to an object of type B. This is trivially true if the two 1276e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// types are the same, or if B is a subclass of A. It becomes more complex 1277e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// in cases where protocols are involved. 1278e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// 1279e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// Object types in Objective-C describe the minimum requirements for an 1280e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// object, rather than providing a complete description of a type. For 1281e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// example, if A is a subclass of B, then B* may refer to an instance of A. 1282e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// The principle of substitutability means that we may use an instance of A 1283e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// anywhere that we may use an instance of B - it will implement all of the 1284e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// ivars of B and all of the methods of B. 1285e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// 1286e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// This substitutability is important when type checking methods, because 1287e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// the implementation may have stricter type definitions than the interface. 1288e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// The interface specifies minimum requirements, but the implementation may 1289e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// have more accurate ones. For example, a method may privately accept 1290e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// instances of B, but only publish that it accepts instances of A. Any 1291e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// object passed to it will be type checked against B, and so will implicitly 1292e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// by a valid A*. Similarly, a method may return a subclass of the class that 1293e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// it is declared as returning. 1294e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// 1295e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// This is most important when considering subclassing. A method in a 1296e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// subclass must accept any object as an argument that its superclass's 1297e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// implementation accepts. It may, however, accept a more general type 1298e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// without breaking substitutability (i.e. you can still use the subclass 1299e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// anywhere that you can use the superclass, but not vice versa). The 1300e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// converse requirement applies to return types: the return type for a 1301e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// subclass method must be a valid object of the kind that the superclass 1302e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// advertises, but it may be specified more accurately. This avoids the need 1303e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// for explicit down-casting by callers. 1304e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// 1305e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// Note: This is a stricter requirement than for assignment. 130610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCallstatic bool isObjCTypeSubstitutable(ASTContext &Context, 130710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall const ObjCObjectPointerType *A, 130810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall const ObjCObjectPointerType *B, 130910302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall bool rejectId) { 131010302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // Reject a protocol-unqualified id. 131110302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall if (rejectId && B->isObjCIdType()) return false; 1312e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall 1313e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // If B is a qualified id, then A must also be a qualified id and it must 1314e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // implement all of the protocols in B. It may not be a qualified class. 1315e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // For example, MyClass<A> can be assigned to id<A>, but MyClass<A> is a 1316e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // stricter definition so it is not substitutable for id<A>. 1317e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall if (B->isObjCQualifiedIdType()) { 1318e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall return A->isObjCQualifiedIdType() && 131910302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall Context.ObjCQualifiedIdTypesAreCompatible(QualType(A, 0), 132010302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall QualType(B,0), 132110302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall false); 1322e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall } 1323e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall 1324e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall /* 1325e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // id is a special type that bypasses type checking completely. We want a 1326e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // warning when it is used in one place but not another. 1327e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall if (C.isObjCIdType(A) || C.isObjCIdType(B)) return false; 1328e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall 1329e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall 1330e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // If B is a qualified id, then A must also be a qualified id (which it isn't 1331e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // if we've got this far) 1332e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall if (B->isObjCQualifiedIdType()) return false; 1333e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall */ 1334e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall 1335e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // Now we know that A and B are (potentially-qualified) class types. The 1336e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // normal rules for assignment apply. 133710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall return Context.canAssignObjCInterfaces(A, B); 1338e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall} 1339e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall 134010302c01e8ceffd86c1a2b1bb15466e852ca8898John McCallstatic SourceRange getTypeRange(TypeSourceInfo *TSI) { 134110302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall return (TSI ? TSI->getTypeLoc().getSourceRange() : SourceRange()); 134210302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall} 134310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 1344fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanianstatic bool CheckMethodOverrideReturn(Sema &S, 134510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall ObjCMethodDecl *MethodImpl, 134621761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian ObjCMethodDecl *MethodDecl, 1347eee3ef177a171c06f826c331e7a9e256d01eaeb0Fariborz Jahanian bool IsProtocolMethodDecl, 1348730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian bool IsOverridingMode, 1349fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian bool Warn) { 135021761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian if (IsProtocolMethodDecl && 135121761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian (MethodDecl->getObjCDeclQualifier() != 135221761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian MethodImpl->getObjCDeclQualifier())) { 1353fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (Warn) { 1354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.Diag(MethodImpl->getLocation(), 1355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (IsOverridingMode 1356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ? diag::warn_conflicting_overriding_ret_type_modifiers 1357651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : diag::warn_conflicting_ret_type_modifiers)) 1358730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian << MethodImpl->getDeclName() 1359176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines << MethodImpl->getReturnTypeSourceRange(); 1360651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration) 1361176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines << MethodDecl->getReturnTypeSourceRange(); 1362fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian } 1363fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian else 1364fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return false; 136521761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian } 1366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1367651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (S.Context.hasSameUnqualifiedType(MethodImpl->getReturnType(), 1368651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MethodDecl->getReturnType())) 1369fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return true; 1370fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (!Warn) 1371fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return false; 137210302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 1373730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian unsigned DiagID = 1374730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian IsOverridingMode ? diag::warn_conflicting_overriding_ret_types 1375730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian : diag::warn_conflicting_ret_types; 137610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 137710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // Mismatches between ObjC pointers go into a different warning 137810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // category, and sometimes they're even completely whitelisted. 137910302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall if (const ObjCObjectPointerType *ImplPtrTy = 1380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MethodImpl->getReturnType()->getAs<ObjCObjectPointerType>()) { 138110302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall if (const ObjCObjectPointerType *IfacePtrTy = 1382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MethodDecl->getReturnType()->getAs<ObjCObjectPointerType>()) { 138310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // Allow non-matching return types as long as they don't violate 138410302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // the principle of substitutability. Specifically, we permit 138510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // return types that are subclasses of the declared return type, 138610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // or that are more-qualified versions of the declared type. 138710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall if (isObjCTypeSubstitutable(S.Context, IfacePtrTy, ImplPtrTy, false)) 1388fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return false; 138910302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 1390730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian DiagID = 1391730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian IsOverridingMode ? diag::warn_non_covariant_overriding_ret_types 1392730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian : diag::warn_non_covariant_ret_types; 139310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall } 139410302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall } 139510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 139610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall S.Diag(MethodImpl->getLocation(), DiagID) 1397651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << MethodImpl->getDeclName() << MethodDecl->getReturnType() 1398651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << MethodImpl->getReturnType() 1399176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines << MethodImpl->getReturnTypeSourceRange(); 1400651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.Diag(MethodDecl->getLocation(), IsOverridingMode 1401651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ? diag::note_previous_declaration 1402651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : diag::note_previous_definition) 1403176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines << MethodDecl->getReturnTypeSourceRange(); 1404fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return false; 140510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall} 140610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 1407fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanianstatic bool CheckMethodOverrideParam(Sema &S, 140810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall ObjCMethodDecl *MethodImpl, 140921761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian ObjCMethodDecl *MethodDecl, 141010302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall ParmVarDecl *ImplVar, 141121761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian ParmVarDecl *IfaceVar, 1412eee3ef177a171c06f826c331e7a9e256d01eaeb0Fariborz Jahanian bool IsProtocolMethodDecl, 1413730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian bool IsOverridingMode, 1414fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian bool Warn) { 141521761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian if (IsProtocolMethodDecl && 141621761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian (ImplVar->getObjCDeclQualifier() != 141721761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian IfaceVar->getObjCDeclQualifier())) { 1418fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (Warn) { 1419730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian if (IsOverridingMode) 1420730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian S.Diag(ImplVar->getLocation(), 1421730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian diag::warn_conflicting_overriding_param_modifiers) 1422730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian << getTypeRange(ImplVar->getTypeSourceInfo()) 1423730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian << MethodImpl->getDeclName(); 1424730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian else S.Diag(ImplVar->getLocation(), 1425fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian diag::warn_conflicting_param_modifiers) 1426fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian << getTypeRange(ImplVar->getTypeSourceInfo()) 1427730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian << MethodImpl->getDeclName(); 1428fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration) 1429fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian << getTypeRange(IfaceVar->getTypeSourceInfo()); 1430fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian } 1431fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian else 1432fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return false; 143321761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian } 143421761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian 143510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall QualType ImplTy = ImplVar->getType(); 143610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall QualType IfaceTy = IfaceVar->getType(); 143721761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian 143810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall if (S.Context.hasSameUnqualifiedType(ImplTy, IfaceTy)) 1439fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return true; 1440fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian 1441fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (!Warn) 1442fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return false; 1443730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian unsigned DiagID = 1444730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian IsOverridingMode ? diag::warn_conflicting_overriding_param_types 1445730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian : diag::warn_conflicting_param_types; 144610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 144710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // Mismatches between ObjC pointers go into a different warning 144810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // category, and sometimes they're even completely whitelisted. 144910302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall if (const ObjCObjectPointerType *ImplPtrTy = 145010302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall ImplTy->getAs<ObjCObjectPointerType>()) { 145110302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall if (const ObjCObjectPointerType *IfacePtrTy = 145210302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall IfaceTy->getAs<ObjCObjectPointerType>()) { 145310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // Allow non-matching argument types as long as they don't 145410302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // violate the principle of substitutability. Specifically, the 145510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // implementation must accept any objects that the superclass 145610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // accepts, however it may also accept others. 145710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall if (isObjCTypeSubstitutable(S.Context, ImplPtrTy, IfacePtrTy, true)) 1458fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return false; 145910302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 1460730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian DiagID = 1461730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian IsOverridingMode ? diag::warn_non_contravariant_overriding_param_types 1462730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian : diag::warn_non_contravariant_param_types; 146310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall } 146410302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall } 146510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 146610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall S.Diag(ImplVar->getLocation(), DiagID) 146710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall << getTypeRange(ImplVar->getTypeSourceInfo()) 1468730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian << MethodImpl->getDeclName() << IfaceTy << ImplTy; 1469730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian S.Diag(IfaceVar->getLocation(), 1470730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian (IsOverridingMode ? diag::note_previous_declaration 1471730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian : diag::note_previous_definition)) 147210302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall << getTypeRange(IfaceVar->getTypeSourceInfo()); 1473fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return false; 147410302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall} 1475f85e193739c953358c865005855253af4f68a497John McCall 1476f85e193739c953358c865005855253af4f68a497John McCall/// In ARC, check whether the conventional meanings of the two methods 1477f85e193739c953358c865005855253af4f68a497John McCall/// match. If they don't, it's a hard error. 1478f85e193739c953358c865005855253af4f68a497John McCallstatic bool checkMethodFamilyMismatch(Sema &S, ObjCMethodDecl *impl, 1479f85e193739c953358c865005855253af4f68a497John McCall ObjCMethodDecl *decl) { 1480f85e193739c953358c865005855253af4f68a497John McCall ObjCMethodFamily implFamily = impl->getMethodFamily(); 1481f85e193739c953358c865005855253af4f68a497John McCall ObjCMethodFamily declFamily = decl->getMethodFamily(); 1482f85e193739c953358c865005855253af4f68a497John McCall if (implFamily == declFamily) return false; 1483f85e193739c953358c865005855253af4f68a497John McCall 1484f85e193739c953358c865005855253af4f68a497John McCall // Since conventions are sorted by selector, the only possibility is 1485f85e193739c953358c865005855253af4f68a497John McCall // that the types differ enough to cause one selector or the other 1486f85e193739c953358c865005855253af4f68a497John McCall // to fall out of the family. 1487f85e193739c953358c865005855253af4f68a497John McCall assert(implFamily == OMF_None || declFamily == OMF_None); 1488f85e193739c953358c865005855253af4f68a497John McCall 1489f85e193739c953358c865005855253af4f68a497John McCall // No further diagnostics required on invalid declarations. 1490f85e193739c953358c865005855253af4f68a497John McCall if (impl->isInvalidDecl() || decl->isInvalidDecl()) return true; 1491f85e193739c953358c865005855253af4f68a497John McCall 1492f85e193739c953358c865005855253af4f68a497John McCall const ObjCMethodDecl *unmatched = impl; 1493f85e193739c953358c865005855253af4f68a497John McCall ObjCMethodFamily family = declFamily; 1494f85e193739c953358c865005855253af4f68a497John McCall unsigned errorID = diag::err_arc_lost_method_convention; 1495f85e193739c953358c865005855253af4f68a497John McCall unsigned noteID = diag::note_arc_lost_method_convention; 1496f85e193739c953358c865005855253af4f68a497John McCall if (declFamily == OMF_None) { 1497f85e193739c953358c865005855253af4f68a497John McCall unmatched = decl; 1498f85e193739c953358c865005855253af4f68a497John McCall family = implFamily; 1499f85e193739c953358c865005855253af4f68a497John McCall errorID = diag::err_arc_gained_method_convention; 1500f85e193739c953358c865005855253af4f68a497John McCall noteID = diag::note_arc_gained_method_convention; 1501f85e193739c953358c865005855253af4f68a497John McCall } 1502f85e193739c953358c865005855253af4f68a497John McCall 1503f85e193739c953358c865005855253af4f68a497John McCall // Indexes into a %select clause in the diagnostic. 1504f85e193739c953358c865005855253af4f68a497John McCall enum FamilySelector { 1505f85e193739c953358c865005855253af4f68a497John McCall F_alloc, F_copy, F_mutableCopy = F_copy, F_init, F_new 1506f85e193739c953358c865005855253af4f68a497John McCall }; 1507f85e193739c953358c865005855253af4f68a497John McCall FamilySelector familySelector = FamilySelector(); 1508f85e193739c953358c865005855253af4f68a497John McCall 1509f85e193739c953358c865005855253af4f68a497John McCall switch (family) { 1510f85e193739c953358c865005855253af4f68a497John McCall case OMF_None: llvm_unreachable("logic error, no method convention"); 1511f85e193739c953358c865005855253af4f68a497John McCall case OMF_retain: 1512f85e193739c953358c865005855253af4f68a497John McCall case OMF_release: 1513f85e193739c953358c865005855253af4f68a497John McCall case OMF_autorelease: 1514f85e193739c953358c865005855253af4f68a497John McCall case OMF_dealloc: 151580cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber case OMF_finalize: 1516f85e193739c953358c865005855253af4f68a497John McCall case OMF_retainCount: 1517f85e193739c953358c865005855253af4f68a497John McCall case OMF_self: 1518176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case OMF_initialize: 15199670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian case OMF_performSelector: 1520f85e193739c953358c865005855253af4f68a497John McCall // Mismatches for these methods don't change ownership 1521f85e193739c953358c865005855253af4f68a497John McCall // conventions, so we don't care. 1522f85e193739c953358c865005855253af4f68a497John McCall return false; 1523f85e193739c953358c865005855253af4f68a497John McCall 1524f85e193739c953358c865005855253af4f68a497John McCall case OMF_init: familySelector = F_init; break; 1525f85e193739c953358c865005855253af4f68a497John McCall case OMF_alloc: familySelector = F_alloc; break; 1526f85e193739c953358c865005855253af4f68a497John McCall case OMF_copy: familySelector = F_copy; break; 1527f85e193739c953358c865005855253af4f68a497John McCall case OMF_mutableCopy: familySelector = F_mutableCopy; break; 1528f85e193739c953358c865005855253af4f68a497John McCall case OMF_new: familySelector = F_new; break; 1529f85e193739c953358c865005855253af4f68a497John McCall } 1530f85e193739c953358c865005855253af4f68a497John McCall 1531f85e193739c953358c865005855253af4f68a497John McCall enum ReasonSelector { R_NonObjectReturn, R_UnrelatedReturn }; 1532f85e193739c953358c865005855253af4f68a497John McCall ReasonSelector reasonSelector; 1533f85e193739c953358c865005855253af4f68a497John McCall 1534f85e193739c953358c865005855253af4f68a497John McCall // The only reason these methods don't fall within their families is 1535f85e193739c953358c865005855253af4f68a497John McCall // due to unusual result types. 1536651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (unmatched->getReturnType()->isObjCObjectPointerType()) { 1537f85e193739c953358c865005855253af4f68a497John McCall reasonSelector = R_UnrelatedReturn; 1538f85e193739c953358c865005855253af4f68a497John McCall } else { 1539f85e193739c953358c865005855253af4f68a497John McCall reasonSelector = R_NonObjectReturn; 1540f85e193739c953358c865005855253af4f68a497John McCall } 1541f85e193739c953358c865005855253af4f68a497John McCall 15427348454025693dd20a411c2bcaabd4460cb87559Joerg Sonnenberger S.Diag(impl->getLocation(), errorID) << int(familySelector) << int(reasonSelector); 15437348454025693dd20a411c2bcaabd4460cb87559Joerg Sonnenberger S.Diag(decl->getLocation(), noteID) << int(familySelector) << int(reasonSelector); 1544f85e193739c953358c865005855253af4f68a497John McCall 1545f85e193739c953358c865005855253af4f68a497John McCall return true; 1546f85e193739c953358c865005855253af4f68a497John McCall} 154710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 15488daab970b80ed2e751fc88327180acbeff1dbb9cFariborz Jahanianvoid Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl, 154921761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian ObjCMethodDecl *MethodDecl, 155036bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian bool IsProtocolMethodDecl) { 15514e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjCAutoRefCount && 1552f85e193739c953358c865005855253af4f68a497John McCall checkMethodFamilyMismatch(*this, ImpMethodDecl, MethodDecl)) 1553f85e193739c953358c865005855253af4f68a497John McCall return; 1554f85e193739c953358c865005855253af4f68a497John McCall 155521761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl, 155636bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian IsProtocolMethodDecl, false, 1557730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian true); 15581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15593aff919532fd807ed678b9cfa4b7eca7b04adcf9Chris Lattner for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(), 15600a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(), 15610a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor EF = MethodDecl->param_end(); 15620a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor IM != EM && IF != EF; ++IM, ++IF) { 156321761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl, *IM, *IF, 156436bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian IsProtocolMethodDecl, false, true); 1565561da7e046ea6b39f4e632c68128fd01c985b46bFariborz Jahanian } 15668daab970b80ed2e751fc88327180acbeff1dbb9cFariborz Jahanian 15672112190efa85f50af84a3c4efe03c5bf69247ba2Fariborz Jahanian if (ImpMethodDecl->isVariadic() != MethodDecl->isVariadic()) { 156836bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian Diag(ImpMethodDecl->getLocation(), 156936bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian diag::warn_conflicting_variadic); 15702112190efa85f50af84a3c4efe03c5bf69247ba2Fariborz Jahanian Diag(MethodDecl->getLocation(), diag::note_previous_declaration); 15712112190efa85f50af84a3c4efe03c5bf69247ba2Fariborz Jahanian } 15722112190efa85f50af84a3c4efe03c5bf69247ba2Fariborz Jahanian} 15732112190efa85f50af84a3c4efe03c5bf69247ba2Fariborz Jahanian 157436bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanianvoid Sema::CheckConflictingOverridingMethod(ObjCMethodDecl *Method, 157536bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian ObjCMethodDecl *Overridden, 157636bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian bool IsProtocolMethodDecl) { 157736bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian 157836bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian CheckMethodOverrideReturn(*this, Method, Overridden, 157936bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian IsProtocolMethodDecl, true, 158036bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian true); 158136bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian 158236bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian for (ObjCMethodDecl::param_iterator IM = Method->param_begin(), 15830a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor IF = Overridden->param_begin(), EM = Method->param_end(), 15840a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor EF = Overridden->param_end(); 15850a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor IM != EM && IF != EF; ++IM, ++IF) { 158636bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian CheckMethodOverrideParam(*this, Method, Overridden, *IM, *IF, 158736bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian IsProtocolMethodDecl, true, true); 158836bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian } 158936bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian 159036bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian if (Method->isVariadic() != Overridden->isVariadic()) { 159136bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian Diag(Method->getLocation(), 159236bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian diag::warn_conflicting_overriding_variadic); 159336bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian Diag(Overridden->getLocation(), diag::note_previous_declaration); 159436bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian } 159536bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian} 159636bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian 1597fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian/// WarnExactTypedMethods - This routine issues a warning if method 1598fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian/// implementation declaration matches exactly that of its declaration. 1599fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanianvoid Sema::WarnExactTypedMethods(ObjCMethodDecl *ImpMethodDecl, 1600fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian ObjCMethodDecl *MethodDecl, 1601fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian bool IsProtocolMethodDecl) { 1602fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // don't issue warning when protocol method is optional because primary 1603fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // class is not required to implement it and it is safe for protocol 1604fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // to implement it. 1605fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (MethodDecl->getImplementationControl() == ObjCMethodDecl::Optional) 1606fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return; 1607fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // don't issue warning when primary class's method is 1608fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // depecated/unavailable. 1609fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (MethodDecl->hasAttr<UnavailableAttr>() || 1610fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian MethodDecl->hasAttr<DeprecatedAttr>()) 1611fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return; 1612fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian 1613fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian bool match = CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl, 1614fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian IsProtocolMethodDecl, false, false); 1615fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (match) 1616fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(), 16170a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(), 16180a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor EF = MethodDecl->param_end(); 16190a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor IM != EM && IF != EF; ++IM, ++IF) { 1620fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian match = CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl, 1621fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian *IM, *IF, 1622fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian IsProtocolMethodDecl, false, false); 1623fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (!match) 1624fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian break; 1625fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian } 1626fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (match) 1627fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian match = (ImpMethodDecl->isVariadic() == MethodDecl->isVariadic()); 16287ca13ef64136929df852c038ebbddee070dc5119David Chisnall if (match) 16297ca13ef64136929df852c038ebbddee070dc5119David Chisnall match = !(MethodDecl->isClassMethod() && 16307ca13ef64136929df852c038ebbddee070dc5119David Chisnall MethodDecl->getSelector() == GetNullarySelector("load", Context)); 1631fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian 1632fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (match) { 1633fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian Diag(ImpMethodDecl->getLocation(), 1634fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian diag::warn_category_method_impl_match); 16353306ec1923973d7b5767b23ba95915af2fec87d7Ted Kremenek Diag(MethodDecl->getLocation(), diag::note_method_declared_at) 16363306ec1923973d7b5767b23ba95915af2fec87d7Ted Kremenek << MethodDecl->getDeclName(); 1637fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian } 1638fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian} 1639fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian 1640390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump/// FIXME: Type hierarchies in Objective-C can be deep. We could most likely 1641390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump/// improve the efficiency of selector lookups and type checking by associating 1642390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump/// with each protocol / interface / category the flattened instance tables. If 1643390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump/// we used an immutable set to keep the table then it wouldn't add significant 1644390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump/// memory cost and it would be handy for lookups. 1645b20ef3e3fbe0fabe213dc0149011e9f0d751a3a4Daniel Dunbar 1646651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef llvm::DenseSet<IdentifierInfo*> ProtocolNameSet; 1647651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef std::unique_ptr<ProtocolNameSet> LazyProtocolNameSet; 1648651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1649651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void findProtocolsWithExplicitImpls(const ObjCProtocolDecl *PDecl, 1650651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ProtocolNameSet &PNS) { 1651651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (PDecl->hasAttr<ObjCExplicitProtocolImplAttr>()) 1652651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PNS.insert(PDecl->getIdentifier()); 1653651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *PI : PDecl->protocols()) 1654651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines findProtocolsWithExplicitImpls(PI, PNS); 1655651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 1656651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1657651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Recursively populates a set with all conformed protocols in a class 1658651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// hierarchy that have the 'objc_protocol_requires_explicit_implementation' 1659651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// attribute. 1660651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void findProtocolsWithExplicitImpls(const ObjCInterfaceDecl *Super, 1661651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ProtocolNameSet &PNS) { 1662651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!Super) 1663651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 1664651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1665651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *I : Super->all_referenced_protocols()) 1666651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines findProtocolsWithExplicitImpls(I, PNS); 1667651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1668651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines findProtocolsWithExplicitImpls(Super->getSuperClass(), PNS); 1669651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 1670651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1671efe7f36f4d87b6e64b87128a81018350b2f21987Steve Naroff/// CheckProtocolMethodDefs - This routine checks unimplemented methods 16724d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// Declared in protocol, and those referenced by it. 1673651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void CheckProtocolMethodDefs(Sema &S, 1674651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation ImpLoc, 1675651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCProtocolDecl *PDecl, 1676651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool& IncompleteImpl, 1677651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Sema::SelectorSet &InsMap, 1678651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Sema::SelectorSet &ClsMap, 1679651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCContainerDecl *CDecl, 1680651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LazyProtocolNameSet &ProtocolsExplictImpl) { 1681bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl); 1682bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian ObjCInterfaceDecl *IDecl = C ? C->getClassInterface() 1683bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian : dyn_cast<ObjCInterfaceDecl>(CDecl); 1684f28385991fa724ac0bd6017d709f17b1838cfea3Fariborz Jahanian assert (IDecl && "CheckProtocolMethodDefs - IDecl is null"); 1685f28385991fa724ac0bd6017d709f17b1838cfea3Fariborz Jahanian 16867ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar ObjCInterfaceDecl *Super = IDecl->getSuperClass(); 16876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ObjCInterfaceDecl *NSIDecl = nullptr; 1688651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1689651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If this protocol is marked 'objc_protocol_requires_explicit_implementation' 1690651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // then we should check if any class in the super class hierarchy also 1691651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // conforms to this protocol, either directly or via protocol inheritance. 1692651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If so, we can skip checking this protocol completely because we 1693651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // know that a parent class already satisfies this protocol. 1694651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // 1695651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Note: we could generalize this logic for all protocols, and merely 1696651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // add the limit on looking at the super class chain for just 1697651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // specially marked protocols. This may be a good optimization. This 1698651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // change is restricted to 'objc_protocol_requires_explicit_implementation' 1699651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // protocols for now for controlled evaluation. 1700651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (PDecl->hasAttr<ObjCExplicitProtocolImplAttr>()) { 1701651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!ProtocolsExplictImpl) { 1702651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ProtocolsExplictImpl.reset(new ProtocolNameSet); 1703651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines findProtocolsWithExplicitImpls(Super, *ProtocolsExplictImpl); 1704651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1705651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (ProtocolsExplictImpl->find(PDecl->getIdentifier()) != 1706651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ProtocolsExplictImpl->end()) 1707651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 1708651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1709651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If no super class conforms to the protocol, we should not search 1710651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // for methods in the super class to implicitly satisfy the protocol. 17116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Super = nullptr; 1712651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1713651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1714651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (S.getLangOpts().ObjCRuntime.isNeXTFamily()) { 17151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // check to see if class implements forwardInvocation method and objects 17161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // of this class are derived from 'NSProxy' so that to forward requests 1717cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian // from one object to another. 17181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Under such conditions, which means that every method possible is 17191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // implemented in the class, we should not issue "Method definition not 1720cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian // found" warnings. 1721cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian // FIXME: Use a general GetUnarySelector method for this. 1722651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IdentifierInfo* II = &S.Context.Idents.get("forwardInvocation"); 1723651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Selector fISelector = S.Context.Selectors.getSelector(1, &II); 1724cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian if (InsMap.count(fISelector)) 1725cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian // Is IDecl derived from 'NSProxy'? If so, no instance methods 1726cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian // need be implemented in the implementation. 1727651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NSIDecl = IDecl->lookupInheritedClass(&S.Context.Idents.get("NSProxy")); 1728cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian } 17291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 173032b94bedc6a789e4091626e7433e73555cf9df00Fariborz Jahanian // If this is a forward protocol declaration, get its definition. 173132b94bedc6a789e4091626e7433e73555cf9df00Fariborz Jahanian if (!PDecl->isThisDeclarationADefinition() && 173232b94bedc6a789e4091626e7433e73555cf9df00Fariborz Jahanian PDecl->getDefinition()) 173332b94bedc6a789e4091626e7433e73555cf9df00Fariborz Jahanian PDecl = PDecl->getDefinition(); 173432b94bedc6a789e4091626e7433e73555cf9df00Fariborz Jahanian 17357ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar // If a method lookup fails locally we still need to look and see if 17367ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar // the method was implemented by a base class or an inherited 17377ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar // protocol. This lookup is slow, but occurs rarely in correct code 17387ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar // and otherwise would terminate in a warning. 17397ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar 17404d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // check unimplemented instance methods. 1741cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian if (!NSIDecl) 1742651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *method : PDecl->instance_methods()) { 17431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (method->getImplementationControl() != ObjCMethodDecl::Optional && 17441e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose !method->isPropertyAccessor() && 17451e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose !InsMap.count(method->getSelector()) && 1746651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (!Super || !Super->lookupMethod(method->getSelector(), 1747651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines true /* instance */, 1748651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines false /* shallowCategory */, 1749651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines true /* followsSuper */, 17506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr /* category */))) { 1751bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian // If a method is not implemented in the category implementation but 1752bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian // has been declared in its primary class, superclass, 1753bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian // or in one of their protocols, no need to issue the warning. 1754bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian // This is because method will be implemented in the primary class 1755bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian // or one of its super class implementation. 1756bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian 1757cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian // Ugly, but necessary. Method declared in protcol might have 1758cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian // have been synthesized due to a property declared in the class which 1759cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian // uses the protocol. 1760bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian if (ObjCMethodDecl *MethodInClass = 1761651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IDecl->lookupMethod(method->getSelector(), 1762651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines true /* instance */, 1763651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines true /* shallowCategoryLookup */, 1764651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines false /* followSuper */)) 17651e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose if (C || MethodInClass->isPropertyAccessor()) 1766bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian continue; 1767bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian unsigned DIAG = diag::warn_unimplemented_protocol_method; 1768c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!S.Diags.isIgnored(DIAG, ImpLoc)) { 1769651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, 1770651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PDecl); 17718822f7cda557ffa755c16b5c978dada23c37d6beFariborz Jahanian } 1772cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian } 1773cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian } 17744d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // check unimplemented class methods 1775651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *method : PDecl->class_methods()) { 17767ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar if (method->getImplementationControl() != ObjCMethodDecl::Optional && 17777ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar !ClsMap.count(method->getSelector()) && 1778651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (!Super || !Super->lookupMethod(method->getSelector(), 1779651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines false /* class method */, 1780651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines false /* shallowCategoryLookup */, 1781651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines true /* followSuper */, 17826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr /* category */))) { 1783bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian // See above comment for instance method lookups. 1784651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (C && IDecl->lookupMethod(method->getSelector(), 1785651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines false /* class */, 1786651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines true /* shallowCategoryLookup */, 1787651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines false /* followSuper */)) 1788bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian continue; 1789651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1790521468391c0abbbfcf6b257442630c70314b8576Fariborz Jahanian unsigned DIAG = diag::warn_unimplemented_protocol_method; 1791c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!S.Diags.isIgnored(DIAG, ImpLoc)) { 1792651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, PDecl); 1793521468391c0abbbfcf6b257442630c70314b8576Fariborz Jahanian } 17948822f7cda557ffa755c16b5c978dada23c37d6beFariborz Jahanian } 179558dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff } 1796780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner // Check on this protocols's referenced protocols, recursively. 1797651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *PI : PDecl->protocols()) 1798651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CheckProtocolMethodDefs(S, ImpLoc, PI, IncompleteImpl, InsMap, ClsMap, 1799651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CDecl, ProtocolsExplictImpl); 18004d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 18014d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 18021e159bc43cf6575a415dbe8deb7fc49611002ffeFariborz Jahanian/// MatchAllMethodDeclarations - Check methods declared in interface 1803b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian/// or protocol against those declared in their implementations. 1804b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian/// 1805811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramervoid Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap, 1806811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer const SelectorSet &ClsMap, 1807811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer SelectorSet &InsMapSeen, 1808811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer SelectorSet &ClsMapSeen, 1809b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian ObjCImplDecl* IMPDecl, 1810b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian ObjCContainerDecl* CDecl, 1811b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian bool &IncompleteImpl, 1812fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian bool ImmediateClass, 1813bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian bool WarnCategoryMethodImpl) { 1814b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // Check and see if instance methods in class interface have been 1815b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // implemented in the implementation class. If so, their types match. 1816651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *I : CDecl->instance_methods()) { 1817176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!InsMapSeen.insert(I->getSelector()).second) 18187dcff5b56bc470c456f70ecb124c3a9013c50953Benjamin Kramer continue; 1819651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!I->isPropertyAccessor() && 1820651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines !InsMap.count(I->getSelector())) { 1821b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian if (ImmediateClass) 1822651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines WarnUndefinedMethod(*this, IMPDecl->getLocation(), I, IncompleteImpl, 18238b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek diag::warn_undef_method_impl); 1824b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian continue; 1825ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 18261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCMethodDecl *ImpMethodDecl = 1827651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IMPDecl->getInstanceMethod(I->getSelector()); 1828651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(CDecl->getInstanceMethod(I->getSelector()) && 18292334f3aeda318f68e763379afa5ac7a91b90caa7Argyrios Kyrtzidis "Expected to find the method through lookup as well"); 1830b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // ImpMethodDecl may be null as in a @dynamic property. 1831fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (ImpMethodDecl) { 1832bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian if (!WarnCategoryMethodImpl) 1833651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines WarnConflictingTypedMethods(ImpMethodDecl, I, 1834fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian isa<ObjCProtocolDecl>(CDecl)); 1835651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else if (!I->isPropertyAccessor()) 1836651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines WarnExactTypedMethods(ImpMethodDecl, I, isa<ObjCProtocolDecl>(CDecl)); 1837fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian } 1838b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian } 1839b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian } 18401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1841b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // Check and see if class methods in class interface have been 1842b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // implemented in the implementation class. If so, their types match. 1843651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *I : CDecl->class_methods()) { 1844176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!ClsMapSeen.insert(I->getSelector()).second) 18457dcff5b56bc470c456f70ecb124c3a9013c50953Benjamin Kramer continue; 1846651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!ClsMap.count(I->getSelector())) { 1847b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian if (ImmediateClass) 1848651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines WarnUndefinedMethod(*this, IMPDecl->getLocation(), I, IncompleteImpl, 18498b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek diag::warn_undef_method_impl); 1850ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 185117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis ObjCMethodDecl *ImpMethodDecl = 1852651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IMPDecl->getClassMethod(I->getSelector()); 1853651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(CDecl->getClassMethod(I->getSelector()) && 18542334f3aeda318f68e763379afa5ac7a91b90caa7Argyrios Kyrtzidis "Expected to find the method through lookup as well"); 1855bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian if (!WarnCategoryMethodImpl) 1856651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines WarnConflictingTypedMethods(ImpMethodDecl, I, 1857fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian isa<ObjCProtocolDecl>(CDecl)); 1858fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian else 1859651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines WarnExactTypedMethods(ImpMethodDecl, I, 1860bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian isa<ObjCProtocolDecl>(CDecl)); 1861b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian } 1862b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian } 1863f54e3aec8a12c3ce453b1012e686c4b88881564aFariborz Jahanian 186441594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl> (CDecl)) { 186541594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian // Also, check for methods declared in protocols inherited by 186641594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian // this protocol. 1867651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *PI : PD->protocols()) 186841594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, 1869651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IMPDecl, PI, IncompleteImpl, false, 187041594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian WarnCategoryMethodImpl); 187141594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian } 187241594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian 1873b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) { 18746a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian // when checking that methods in implementation match their declaration, 18756a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian // i.e. when WarnCategoryMethodImpl is false, check declarations in class 18766a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian // extension; as well as those in categories. 1877d329724745b49f894b768d47275b7c2713106e89Douglas Gregor if (!WarnCategoryMethodImpl) { 1878651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *Cat : I->visible_categories()) 18796a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, 1880651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IMPDecl, Cat, IncompleteImpl, false, 18816a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian WarnCategoryMethodImpl); 1882d329724745b49f894b768d47275b7c2713106e89Douglas Gregor } else { 18836a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian // Also methods in class extensions need be looked at next. 1884651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *Ext : I->visible_extensions()) 18856a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, 1886651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IMPDecl, Ext, IncompleteImpl, false, 18876a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian WarnCategoryMethodImpl); 1888d329724745b49f894b768d47275b7c2713106e89Douglas Gregor } 1889d329724745b49f894b768d47275b7c2713106e89Douglas Gregor 1890b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // Check for any implementation of a methods declared in protocol. 1891651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *PI : I->all_referenced_protocols()) 18921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, 1893651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IMPDecl, PI, IncompleteImpl, false, 1894bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian WarnCategoryMethodImpl); 1895651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1896fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // FIXME. For now, we are not checking for extact match of methods 1897fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // in category implementation and its primary class's super class. 1898bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian if (!WarnCategoryMethodImpl && I->getSuperClass()) 1899b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, 19001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump IMPDecl, 1901b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian I->getSuperClass(), IncompleteImpl, false); 1902b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian } 1903b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian} 1904b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian 1905fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian/// CheckCategoryVsClassMethodMatches - Checks that methods implemented in 1906fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian/// category matches with those implemented in its primary class and 1907fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian/// warns each time an exact match is found. 1908fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanianvoid Sema::CheckCategoryVsClassMethodMatches( 1909fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian ObjCCategoryImplDecl *CatIMPDecl) { 1910fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // Get category's primary class. 1911fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian ObjCCategoryDecl *CatDecl = CatIMPDecl->getCategoryDecl(); 1912fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (!CatDecl) 1913fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return; 1914fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian ObjCInterfaceDecl *IDecl = CatDecl->getClassInterface(); 1915fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (!IDecl) 1916fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return; 1917651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCInterfaceDecl *SuperIDecl = IDecl->getSuperClass(); 1918651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SelectorSet InsMap, ClsMap; 1919651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1920651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *I : CatIMPDecl->instance_methods()) { 1921651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Selector Sel = I->getSelector(); 1922651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // When checking for methods implemented in the category, skip over 1923651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // those declared in category class's super class. This is because 1924651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // the super class must implement the method. 1925651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (SuperIDecl && SuperIDecl->lookupMethod(Sel, true)) 1926651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 1927651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines InsMap.insert(Sel); 1928651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1929651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1930651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *I : CatIMPDecl->class_methods()) { 1931651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Selector Sel = I->getSelector(); 1932651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (SuperIDecl && SuperIDecl->lookupMethod(Sel, false)) 1933651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 1934651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ClsMap.insert(Sel); 1935651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1936651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (InsMap.empty() && ClsMap.empty()) 1937651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 1938651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1939811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer SelectorSet InsMapSeen, ClsMapSeen; 1940fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian bool IncompleteImpl = false; 1941fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, 1942fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian CatIMPDecl, IDecl, 1943bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian IncompleteImpl, false, 1944bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian true /*WarnCategoryMethodImpl*/); 1945fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian} 1946eee3ef177a171c06f826c331e7a9e256d01eaeb0Fariborz Jahanian 194717cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanianvoid Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, 19481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCContainerDecl* CDecl, 1949cddc88800bbd1213ec70ae5153c6a7f2e380fd8dChris Lattner bool IncompleteImpl) { 1950811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer SelectorSet InsMap; 19514d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check and see if instance methods in class interface have been 19524d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // implemented in the implementation class. 1953651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *I : IMPDecl->instance_methods()) 1954651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines InsMap.insert(I->getSelector()); 19551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 195612bac2566e3136d4bd9d42e6aabe27e1038f7793Fariborz Jahanian // Check and see if properties declared in the interface have either 1) 195712bac2566e3136d4bd9d42e6aabe27e1038f7793Fariborz Jahanian // an implementation or 2) there is a @synthesize/@dynamic implementation 195812bac2566e3136d4bd9d42e6aabe27e1038f7793Fariborz Jahanian // of the property in the @implementation. 1959651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) { 1960651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool SynthesizeProperties = LangOpts.ObjCDefaultSynthProperties && 1961651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LangOpts.ObjCRuntime.isNonFragile() && 1962651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines !IDecl->isObjCRequiresPropertyDefs(); 1963651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, SynthesizeProperties); 1964651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1965651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1966811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer SelectorSet ClsMap; 1967651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *I : IMPDecl->class_methods()) 1968651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ClsMap.insert(I->getSelector()); 19691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1970b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // Check for type conflict of methods declared in a class/protocol and 1971b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // its implementation; if any. 1972811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer SelectorSet InsMapSeen, ClsMapSeen; 19731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, 19741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump IMPDecl, CDecl, 1975b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian IncompleteImpl, true); 197674133075f5024ce87e4c1eb644d77c20e1c521f4Fariborz Jahanian 1977fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // check all methods implemented in category against those declared 1978fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // in its primary class. 1979fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (ObjCCategoryImplDecl *CatDecl = 1980fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian dyn_cast<ObjCCategoryImplDecl>(IMPDecl)) 1981fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian CheckCategoryVsClassMethodMatches(CatDecl); 19821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19834d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check the protocol list for unimplemented methods in the @implementation 19844d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // class. 1985b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // Check and see if class methods in class interface have been 1986b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // implemented in the implementation class. 19871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1988651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LazyProtocolNameSet ExplicitImplProtocols; 1989651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1990cddc88800bbd1213ec70ae5153c6a7f2e380fd8dChris Lattner if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) { 1991651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *PI : I->all_referenced_protocols()) 1992651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), PI, IncompleteImpl, 1993651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines InsMap, ClsMap, I, ExplicitImplProtocols); 1994cddc88800bbd1213ec70ae5153c6a7f2e380fd8dChris Lattner // Check class extensions (unnamed categories) 1995651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *Ext : I->visible_extensions()) 1996651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ImplMethodsVsClassMethods(S, IMPDecl, Ext, IncompleteImpl); 1997cddc88800bbd1213ec70ae5153c6a7f2e380fd8dChris Lattner } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) { 1998b106fc635b1523952332131785b700453a936e49Fariborz Jahanian // For extended class, unimplemented methods in its protocols will 1999b106fc635b1523952332131785b700453a936e49Fariborz Jahanian // be reported in the primary class. 200025760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian if (!C->IsClassExtension()) { 2001651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *P : C->protocols()) 2002651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), P, 2003651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IncompleteImpl, InsMap, ClsMap, CDecl, 2004651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExplicitImplProtocols); 2005651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, 20060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /*SynthesizeProperties=*/false); 20073ad230eb626d630877c17d6e81b167ec7476d84eFariborz Jahanian } 2008cddc88800bbd1213ec70ae5153c6a7f2e380fd8dChris Lattner } else 2009b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("invalid ObjCContainerDecl type."); 20104d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 20114d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 201295ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz JahanianSema::DeclGroupPtrTy 20134d3914836e85258e9ace7306999413e3c7ea6c11Chris LattnerSema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, 2014bdbde4db74ea9751e02081d720f415eae9718662Chris Lattner IdentifierInfo **IdentList, 2015c09cba67d0ad01e53e0fed07322e95dd281bcfd9Ted Kremenek SourceLocation *IdentLocs, 2016bdbde4db74ea9751e02081d720f415eae9718662Chris Lattner unsigned NumElts) { 201795ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian SmallVector<Decl *, 8> DeclsInGroup; 20184d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner for (unsigned i = 0; i != NumElts; ++i) { 20194d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check for another declaration kind with the same name. 2020f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *PrevDecl 2021c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor = LookupSingleName(TUScope, IdentList[i], IdentLocs[i], 2022c0b39640de335809ca7544f802751112619f30ccDouglas Gregor LookupOrdinaryName, ForRedeclaration); 2023a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) { 2024c7333881dcd00be87814d03c349dd96c815f2f05Steve Naroff // GCC apparently allows the following idiom: 2025c7333881dcd00be87814d03c349dd96c815f2f05Steve Naroff // 2026c7333881dcd00be87814d03c349dd96c815f2f05Steve Naroff // typedef NSObject < XCElementTogglerP > XCElementToggler; 2027c7333881dcd00be87814d03c349dd96c815f2f05Steve Naroff // @class XCElementToggler; 2028c7333881dcd00be87814d03c349dd96c815f2f05Steve Naroff // 2029e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian // Here we have chosen to ignore the forward class declaration 2030e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian // with a warning. Since this is the implied behavior. 2031162e1c1b487352434552147967c3dd296ebee2f7Richard Smith TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(PrevDecl); 2032c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall if (!TDD || !TDD->getUnderlyingType()->isObjCObjectType()) { 20333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(AtClassLoc, diag::err_redefinition_different_kind) << IdentList[i]; 20345f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(PrevDecl->getLocation(), diag::note_previous_definition); 2035c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall } else { 2036ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump // a forward class declaration matching a typedef name of a class refers 2037e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian // to the underlying class. Just ignore the forward class with a warning 20380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // as this will force the intended behavior which is to lookup the 20390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // typedef name. 2040e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian if (isa<ObjCObjectType>(TDD->getUnderlyingType())) { 20410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Diag(AtClassLoc, diag::warn_forward_class_redefinition) 20420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines << IdentList[i]; 2043e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian Diag(PrevDecl->getLocation(), diag::note_previous_definition); 2044e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian continue; 2045e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian } 2046cae27c51f0da674cdd3b53b8b2f7ba08c44c54b0Fariborz Jahanian } 20474d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 20487723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor 20497723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor // Create a declaration to describe this forward declaration. 20500af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor ObjCInterfaceDecl *PrevIDecl 20510af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl); 2052e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis 2053e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis IdentifierInfo *ClassName = IdentList[i]; 2054e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) { 2055e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // A previous decl with a different name is because of 2056e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // @compatibility_alias, for example: 2057e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // \code 2058e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // @class NewImage; 2059e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // @compatibility_alias OldImage NewImage; 2060e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // \endcode 2061e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // A lookup for 'OldImage' will return the 'NewImage' decl. 2062e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // 2063e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // In such a case use the real declaration name, instead of the alias one, 2064e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // otherwise we will break IdentifierResolver and redecls-chain invariants. 2065e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // FIXME: If necessary, add a bit to indicate that this ObjCInterfaceDecl 2066e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // has been aliased. 2067e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis ClassName = PrevIDecl->getIdentifier(); 2068e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis } 2069e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis 20707723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor ObjCInterfaceDecl *IDecl 20717723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc, 2072e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis ClassName, PrevIDecl, IdentLocs[i]); 20737723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor IDecl->setAtEndRange(IdentLocs[i]); 20747723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor 20757723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor PushOnScopeChains(IDecl, TUScope); 2076375bb1413c041055262c8a416f20d10474a5eda9Douglas Gregor CheckObjCDeclScope(IDecl); 2077375bb1413c041055262c8a416f20d10474a5eda9Douglas Gregor DeclsInGroup.push_back(IDecl); 20784d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 20794549d7ffc15bdd7ab860aa68db089d9f559b79e7Rafael Espindola 20804549d7ffc15bdd7ab860aa68db089d9f559b79e7Rafael Espindola return BuildDeclaratorGroup(DeclsInGroup, false); 20814d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 20824d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 20830f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCallstatic bool tryMatchRecordTypes(ASTContext &Context, 20840f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall Sema::MethodMatchStrategy strategy, 20850f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall const Type *left, const Type *right); 20860f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall 2087f85e193739c953358c865005855253af4f68a497John McCallstatic bool matchTypes(ASTContext &Context, Sema::MethodMatchStrategy strategy, 2088f85e193739c953358c865005855253af4f68a497John McCall QualType leftQT, QualType rightQT) { 2089f85e193739c953358c865005855253af4f68a497John McCall const Type *left = 2090f85e193739c953358c865005855253af4f68a497John McCall Context.getCanonicalType(leftQT).getUnqualifiedType().getTypePtr(); 2091f85e193739c953358c865005855253af4f68a497John McCall const Type *right = 2092f85e193739c953358c865005855253af4f68a497John McCall Context.getCanonicalType(rightQT).getUnqualifiedType().getTypePtr(); 2093f85e193739c953358c865005855253af4f68a497John McCall 2094f85e193739c953358c865005855253af4f68a497John McCall if (left == right) return true; 2095f85e193739c953358c865005855253af4f68a497John McCall 2096f85e193739c953358c865005855253af4f68a497John McCall // If we're doing a strict match, the types have to match exactly. 2097f85e193739c953358c865005855253af4f68a497John McCall if (strategy == Sema::MMS_strict) return false; 2098f85e193739c953358c865005855253af4f68a497John McCall 2099f85e193739c953358c865005855253af4f68a497John McCall if (left->isIncompleteType() || right->isIncompleteType()) return false; 2100f85e193739c953358c865005855253af4f68a497John McCall 2101f85e193739c953358c865005855253af4f68a497John McCall // Otherwise, use this absurdly complicated algorithm to try to 2102f85e193739c953358c865005855253af4f68a497John McCall // validate the basic, low-level compatibility of the two types. 2103f85e193739c953358c865005855253af4f68a497John McCall 2104f85e193739c953358c865005855253af4f68a497John McCall // As a minimum, require the sizes and alignments to match. 2105176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TypeInfo LeftTI = Context.getTypeInfo(left); 2106176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TypeInfo RightTI = Context.getTypeInfo(right); 2107176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (LeftTI.Width != RightTI.Width) 2108176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return false; 2109176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 2110176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (LeftTI.Align != RightTI.Align) 2111f85e193739c953358c865005855253af4f68a497John McCall return false; 2112f85e193739c953358c865005855253af4f68a497John McCall 2113f85e193739c953358c865005855253af4f68a497John McCall // Consider all the kinds of non-dependent canonical types: 2114f85e193739c953358c865005855253af4f68a497John McCall // - functions and arrays aren't possible as return and parameter types 2115f85e193739c953358c865005855253af4f68a497John McCall 2116f85e193739c953358c865005855253af4f68a497John McCall // - vector types of equal size can be arbitrarily mixed 2117f85e193739c953358c865005855253af4f68a497John McCall if (isa<VectorType>(left)) return isa<VectorType>(right); 2118f85e193739c953358c865005855253af4f68a497John McCall if (isa<VectorType>(right)) return false; 2119f85e193739c953358c865005855253af4f68a497John McCall 2120f85e193739c953358c865005855253af4f68a497John McCall // - references should only match references of identical type 21210f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall // - structs, unions, and Objective-C objects must match more-or-less 21220f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall // exactly 2123f85e193739c953358c865005855253af4f68a497John McCall // - everything else should be a scalar 2124f85e193739c953358c865005855253af4f68a497John McCall if (!left->isScalarType() || !right->isScalarType()) 21250f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall return tryMatchRecordTypes(Context, strategy, left, right); 2126f85e193739c953358c865005855253af4f68a497John McCall 21271d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall // Make scalars agree in kind, except count bools as chars, and group 21281d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall // all non-member pointers together. 2129f85e193739c953358c865005855253af4f68a497John McCall Type::ScalarTypeKind leftSK = left->getScalarTypeKind(); 2130f85e193739c953358c865005855253af4f68a497John McCall Type::ScalarTypeKind rightSK = right->getScalarTypeKind(); 2131f85e193739c953358c865005855253af4f68a497John McCall if (leftSK == Type::STK_Bool) leftSK = Type::STK_Integral; 2132f85e193739c953358c865005855253af4f68a497John McCall if (rightSK == Type::STK_Bool) rightSK = Type::STK_Integral; 21331d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall if (leftSK == Type::STK_CPointer || leftSK == Type::STK_BlockPointer) 21341d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall leftSK = Type::STK_ObjCObjectPointer; 21351d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall if (rightSK == Type::STK_CPointer || rightSK == Type::STK_BlockPointer) 21361d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall rightSK = Type::STK_ObjCObjectPointer; 2137f85e193739c953358c865005855253af4f68a497John McCall 2138f85e193739c953358c865005855253af4f68a497John McCall // Note that data member pointers and function member pointers don't 2139f85e193739c953358c865005855253af4f68a497John McCall // intermix because of the size differences. 2140f85e193739c953358c865005855253af4f68a497John McCall 2141f85e193739c953358c865005855253af4f68a497John McCall return (leftSK == rightSK); 2142f85e193739c953358c865005855253af4f68a497John McCall} 21434d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 21440f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCallstatic bool tryMatchRecordTypes(ASTContext &Context, 21450f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall Sema::MethodMatchStrategy strategy, 21460f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall const Type *lt, const Type *rt) { 21470f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall assert(lt && rt && lt != rt); 21480f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall 21490f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall if (!isa<RecordType>(lt) || !isa<RecordType>(rt)) return false; 21500f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall RecordDecl *left = cast<RecordType>(lt)->getDecl(); 21510f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall RecordDecl *right = cast<RecordType>(rt)->getDecl(); 21520f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall 21530f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall // Require union-hood to match. 21540f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall if (left->isUnion() != right->isUnion()) return false; 21550f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall 21560f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall // Require an exact match if either is non-POD. 21570f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall if ((isa<CXXRecordDecl>(left) && !cast<CXXRecordDecl>(left)->isPOD()) || 21580f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall (isa<CXXRecordDecl>(right) && !cast<CXXRecordDecl>(right)->isPOD())) 21590f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall return false; 21600f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall 21610f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall // Require size and alignment to match. 2162176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TypeInfo LeftTI = Context.getTypeInfo(lt); 2163176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TypeInfo RightTI = Context.getTypeInfo(rt); 2164176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (LeftTI.Width != RightTI.Width) 2165176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return false; 2166176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 2167176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (LeftTI.Align != RightTI.Align) 2168176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return false; 21690f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall 21700f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall // Require fields to match. 21710f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall RecordDecl::field_iterator li = left->field_begin(), le = left->field_end(); 21720f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall RecordDecl::field_iterator ri = right->field_begin(), re = right->field_end(); 21730f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall for (; li != le && ri != re; ++li, ++ri) { 21740f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall if (!matchTypes(Context, strategy, li->getType(), ri->getType())) 21750f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall return false; 21760f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall } 21770f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall return (li == le && ri == re); 21780f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall} 21790f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall 21804d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// MatchTwoMethodDeclarations - Checks that two methods have matching type and 21814d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// returns true, or false, accordingly. 21824d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// TODO: Handle protocol list; such as id<p1,p2> in type comparisons 2183f85e193739c953358c865005855253af4f68a497John McCallbool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *left, 2184f85e193739c953358c865005855253af4f68a497John McCall const ObjCMethodDecl *right, 2185f85e193739c953358c865005855253af4f68a497John McCall MethodMatchStrategy strategy) { 2186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!matchTypes(Context, strategy, left->getReturnType(), 2187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines right->getReturnType())) 2188f85e193739c953358c865005855253af4f68a497John McCall return false; 21891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 21907666b03d499819214752ae392efe666ca856d0e7Douglas Gregor // If either is hidden, it is not considered to match. 21917666b03d499819214752ae392efe666ca856d0e7Douglas Gregor if (left->isHidden() || right->isHidden()) 21927666b03d499819214752ae392efe666ca856d0e7Douglas Gregor return false; 21937666b03d499819214752ae392efe666ca856d0e7Douglas Gregor 21944e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjCAutoRefCount && 2195f85e193739c953358c865005855253af4f68a497John McCall (left->hasAttr<NSReturnsRetainedAttr>() 2196f85e193739c953358c865005855253af4f68a497John McCall != right->hasAttr<NSReturnsRetainedAttr>() || 2197f85e193739c953358c865005855253af4f68a497John McCall left->hasAttr<NSConsumesSelfAttr>() 2198f85e193739c953358c865005855253af4f68a497John McCall != right->hasAttr<NSConsumesSelfAttr>())) 2199f85e193739c953358c865005855253af4f68a497John McCall return false; 22001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2201491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis ObjCMethodDecl::param_const_iterator 22020a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor li = left->param_begin(), le = left->param_end(), ri = right->param_begin(), 22030a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor re = right->param_end(); 2204f85e193739c953358c865005855253af4f68a497John McCall 22050a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor for (; li != le && ri != re; ++li, ++ri) { 2206f85e193739c953358c865005855253af4f68a497John McCall assert(ri != right->param_end() && "Param mismatch"); 2207491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis const ParmVarDecl *lparm = *li, *rparm = *ri; 2208f85e193739c953358c865005855253af4f68a497John McCall 2209f85e193739c953358c865005855253af4f68a497John McCall if (!matchTypes(Context, strategy, lparm->getType(), rparm->getType())) 2210f85e193739c953358c865005855253af4f68a497John McCall return false; 2211f85e193739c953358c865005855253af4f68a497John McCall 22124e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjCAutoRefCount && 2213f85e193739c953358c865005855253af4f68a497John McCall lparm->hasAttr<NSConsumedAttr>() != rparm->hasAttr<NSConsumedAttr>()) 2214f85e193739c953358c865005855253af4f68a497John McCall return false; 22154d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 22164d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner return true; 22174d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 22184d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 22190e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid Sema::addMethodToGlobalList(ObjCMethodList *List, 22200e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ObjCMethodDecl *Method) { 22212e3d8c0815acaf1bc5995ebe56cea07471e5c9c7Argyrios Kyrtzidis // Record at the head of the list whether there were 0, 1, or >= 2 methods 22222e3d8c0815acaf1bc5995ebe56cea07471e5c9c7Argyrios Kyrtzidis // inside categories. 22230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (ObjCCategoryDecl *CD = 22240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) 2225ab3d509bc45218c278454962ff644bb13d18ce1aArgyrios Kyrtzidis if (!CD->IsClassExtension() && List->getBits() < 2) 22260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines List->setBits(List->getBits() + 1); 22272e3d8c0815acaf1bc5995ebe56cea07471e5c9c7Argyrios Kyrtzidis 222844fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // If the list is empty, make it a singleton list. 22290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (List->getMethod() == nullptr) { 22300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines List->setMethod(Method); 22316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines List->setNext(nullptr); 2232ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor return; 223344fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor } 22340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 223544fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // We've seen a method with this name, see if we have already seen this type 223644fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // signature. 223744fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor ObjCMethodList *Previous = List; 22382e3d8c0815acaf1bc5995ebe56cea07471e5c9c7Argyrios Kyrtzidis for (; List; Previous = List, List = List->getNext()) { 2239fc46be997f8219e11900473c373b639525396064Douglas Gregor // If we are building a module, keep all of the methods. 2240fc46be997f8219e11900473c373b639525396064Douglas Gregor if (getLangOpts().Modules && !getLangOpts().CurrentModule.empty()) 2241fc46be997f8219e11900473c373b639525396064Douglas Gregor continue; 2242fc46be997f8219e11900473c373b639525396064Douglas Gregor 224333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (!MatchTwoMethodDeclarations(Method, List->getMethod())) { 224433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Even if two method types do not match, we would like to say 224533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // there is more than one declaration so unavailability/deprecated 224633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // warning is not too noisy. 224733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (!Method->isDefined()) 224833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar List->setHasMoreThanOneDecl(true); 224944fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor continue; 225033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 22510e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 22520e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ObjCMethodDecl *PrevObjCMethod = List->getMethod(); 225344fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor 225444fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // Propagate the 'defined' bit. 225544fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor if (Method->isDefined()) 225644fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor PrevObjCMethod->setDefined(true); 22570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines else { 22580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Objective-C doesn't allow an @interface for a class after its 22590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // @implementation. So if Method is not defined and there already is 22600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // an entry for this type signature, Method has to be for a different 22610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // class than PrevObjCMethod. 22620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines List->setHasMoreThanOneDecl(true); 22630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 22640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 226544fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // If a method is deprecated, push it in the global pool. 226644fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // This is used for better diagnostics. 226744fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor if (Method->isDeprecated()) { 226844fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor if (!PrevObjCMethod->isDeprecated()) 22690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines List->setMethod(Method); 227044fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor } 22710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // If the new method is unavailable, push it into global pool 227244fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // unless previous one is deprecated. 227344fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor if (Method->isUnavailable()) { 227444fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor if (PrevObjCMethod->getAvailability() < AR_Deprecated) 22750e2c34f92f00628d48968dfea096d36381f494cbStephen Hines List->setMethod(Method); 227644fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor } 22770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 2278ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor return; 227944fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor } 22800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 228144fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // We have a new signature for an existing method - add it. 228244fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // This is extremely rare. Only 1% of Cocoa selectors are "overloaded". 22835ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>(); 22840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Previous->setNext(new (Mem) ObjCMethodList(Method)); 228544fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor} 228644fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor 2287db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl/// \brief Read the contents of the method pool for a given selector from 2288db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl/// external storage. 22895ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregorvoid Sema::ReadMethodPool(Selector Sel) { 2290f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor assert(ExternalSource && "We need an external AST source"); 22915ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor ExternalSource->ReadMethodPool(Sel); 2292f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor} 2293f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor 2294ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregorvoid Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, 2295db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl bool instance) { 22969a0b6b4e2bf6a9ef41d32b4e83f2911981d2d44dArgyrios Kyrtzidis // Ignore methods of invalid containers. 22979a0b6b4e2bf6a9ef41d32b4e83f2911981d2d44dArgyrios Kyrtzidis if (cast<Decl>(Method->getDeclContext())->isInvalidDecl()) 2298ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor return; 22999a0b6b4e2bf6a9ef41d32b4e83f2911981d2d44dArgyrios Kyrtzidis 23000d266d623452f09d06973528217390d762a8f3faDouglas Gregor if (ExternalSource) 23010d266d623452f09d06973528217390d762a8f3faDouglas Gregor ReadMethodPool(Method->getSelector()); 23020d266d623452f09d06973528217390d762a8f3faDouglas Gregor 2303db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl GlobalMethodPool::iterator Pos = MethodPool.find(Method->getSelector()); 23040d266d623452f09d06973528217390d762a8f3faDouglas Gregor if (Pos == MethodPool.end()) 23050d266d623452f09d06973528217390d762a8f3faDouglas Gregor Pos = MethodPool.insert(std::make_pair(Method->getSelector(), 23060d266d623452f09d06973528217390d762a8f3faDouglas Gregor GlobalMethods())).first; 23070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 23083fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian Method->setDefined(impl); 230944fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor 2310db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl ObjCMethodList &Entry = instance ? Pos->second.first : Pos->second.second; 2311ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor addMethodToGlobalList(&Entry, Method); 23124d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 23134d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 2314f85e193739c953358c865005855253af4f68a497John McCall/// Determines if this is an "acceptable" loose mismatch in the global 2315f85e193739c953358c865005855253af4f68a497John McCall/// method pool. This exists mostly as a hack to get around certain 2316f85e193739c953358c865005855253af4f68a497John McCall/// global mismatches which we can't afford to make warnings / errors. 2317f85e193739c953358c865005855253af4f68a497John McCall/// Really, what we want is a way to take a method out of the global 2318f85e193739c953358c865005855253af4f68a497John McCall/// method pool. 2319f85e193739c953358c865005855253af4f68a497John McCallstatic bool isAcceptableMethodMismatch(ObjCMethodDecl *chosen, 2320f85e193739c953358c865005855253af4f68a497John McCall ObjCMethodDecl *other) { 2321f85e193739c953358c865005855253af4f68a497John McCall if (!chosen->isInstanceMethod()) 2322f85e193739c953358c865005855253af4f68a497John McCall return false; 2323f85e193739c953358c865005855253af4f68a497John McCall 2324f85e193739c953358c865005855253af4f68a497John McCall Selector sel = chosen->getSelector(); 2325f85e193739c953358c865005855253af4f68a497John McCall if (!sel.isUnarySelector() || sel.getNameForSlot(0) != "length") 2326f85e193739c953358c865005855253af4f68a497John McCall return false; 2327f85e193739c953358c865005855253af4f68a497John McCall 2328f85e193739c953358c865005855253af4f68a497John McCall // Don't complain about mismatches for -length if the method we 2329f85e193739c953358c865005855253af4f68a497John McCall // chose has an integral result type. 2330651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return (chosen->getReturnType()->isIntegerType()); 2331f85e193739c953358c865005855253af4f68a497John McCall} 2332f85e193739c953358c865005855253af4f68a497John McCall 23330e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesbool Sema::CollectMultipleMethodsInGlobalPool( 23340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Selector Sel, SmallVectorImpl<ObjCMethodDecl *> &Methods, bool instance) { 2335176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (ExternalSource) 2336176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ReadMethodPool(Sel); 2337176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 2338176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines GlobalMethodPool::iterator Pos = MethodPool.find(Sel); 2339176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (Pos == MethodPool.end()) 2340176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return false; 2341176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Gather the non-hidden methods. 2342176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second; 2343176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines for (ObjCMethodList *M = &MethList; M; M = M->getNext()) 23440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (M->getMethod() && !M->getMethod()->isHidden()) 23450e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Methods.push_back(M->getMethod()); 23460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return Methods.size() > 1; 2347176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 2348176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 234933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarbool Sema::AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, 235033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar SourceRange R, 235133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar bool receiverIdOrClass) { 2352176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines GlobalMethodPool::iterator Pos = MethodPool.find(Sel); 23530e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Test for no method in the pool which should not trigger any warning by 23540e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // caller. 2355176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (Pos == MethodPool.end()) 2356176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return true; 235733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ObjCMethodList &MethList = 235833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar BestMethod->isInstanceMethod() ? Pos->second.first : Pos->second.second; 235933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 236033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar // Diagnose finding more than one method in global pool 236133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar SmallVector<ObjCMethodDecl *, 4> Methods; 236233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Methods.push_back(BestMethod); 236333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar for (ObjCMethodList *M = &MethList; M; M = M->getNext()) 236433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (M->getMethod() && !M->getMethod()->isHidden() && 236533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar M->getMethod() != BestMethod) 236633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Methods.push_back(M->getMethod()); 236733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (Methods.size() > 1) 236833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar DiagnoseMultipleMethodInGlobalPool(Methods, Sel, R, receiverIdOrClass); 236933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 23700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return MethList.hasMoreThanOneDecl(); 2371176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 2372176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 2373db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian RedlObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R, 23746b308f6dc7d8f1581c52095f435c0e1284b111d8Fariborz Jahanian bool receiverIdOrClass, 237533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar bool instance) { 23760d266d623452f09d06973528217390d762a8f3faDouglas Gregor if (ExternalSource) 23770d266d623452f09d06973528217390d762a8f3faDouglas Gregor ReadMethodPool(Sel); 23780d266d623452f09d06973528217390d762a8f3faDouglas Gregor 2379db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl GlobalMethodPool::iterator Pos = MethodPool.find(Sel); 23800d266d623452f09d06973528217390d762a8f3faDouglas Gregor if (Pos == MethodPool.end()) 23816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2382f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor 2383f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor // Gather the non-hidden methods. 2384db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second; 2385e7205c0e2472dd66238f4c6b6db1b7cc2957b42aRobert Wilhelm SmallVector<ObjCMethodDecl *, 4> Methods; 23862e3d8c0815acaf1bc5995ebe56cea07471e5c9c7Argyrios Kyrtzidis for (ObjCMethodList *M = &MethList; M; M = M->getNext()) { 238733337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (M->getMethod() && !M->getMethod()->isHidden()) 238833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar return M->getMethod(); 2389f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor } 239033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar return nullptr; 239133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar} 23921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 239333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainarvoid Sema::DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl*> &Methods, 239433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar Selector Sel, SourceRange R, 239533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar bool receiverIdOrClass) { 2396f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor // We found multiple methods, so we may have to complain. 2397f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor bool issueDiagnostic = false, issueError = false; 239833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 2399f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor // We support a warning which complains about *any* difference in 2400f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor // method signature. 2401f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor bool strictSelectorMatch = 240233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar receiverIdOrClass && 240333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar !Diags.isIgnored(diag::warn_strict_multiple_method_decl, R.getBegin()); 2404f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor if (strictSelectorMatch) { 2405f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor for (unsigned I = 1, N = Methods.size(); I != N; ++I) { 2406f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_strict)) { 2407f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor issueDiagnostic = true; 2408f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor break; 24096b308f6dc7d8f1581c52095f435c0e1284b111d8Fariborz Jahanian } 2410f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor } 2411f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor } 241233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 2413f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor // If we didn't see any strict differences, we won't see any loose 2414f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor // differences. In ARC, however, we also need to check for loose 2415f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor // mismatches, because most of them are errors. 2416f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor if (!strictSelectorMatch || 2417f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor (issueDiagnostic && getLangOpts().ObjCAutoRefCount)) 2418f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor for (unsigned I = 1, N = Methods.size(); I != N; ++I) { 2419f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor // This checks if the methods differ in type mismatch. 2420f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_loose) && 2421f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor !isAcceptableMethodMismatch(Methods[0], Methods[I])) { 2422f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor issueDiagnostic = true; 2423f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor if (getLangOpts().ObjCAutoRefCount) 2424f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor issueError = true; 2425f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor break; 2426f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor } 24274d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 242833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 2429f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor if (issueDiagnostic) { 2430f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor if (issueError) 2431f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor Diag(R.getBegin(), diag::err_arc_multiple_method_decl) << Sel << R; 2432f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor else if (strictSelectorMatch) 2433f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor Diag(R.getBegin(), diag::warn_strict_multiple_method_decl) << Sel << R; 2434f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor else 2435f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R; 243633337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar 2437f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor Diag(Methods[0]->getLocStart(), 2438f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor issueError ? diag::note_possibility : diag::note_using) 243933337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar << Methods[0]->getSourceRange(); 2440f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor for (unsigned I = 1, N = Methods.size(); I != N; ++I) { 2441f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor Diag(Methods[I]->getLocStart(), diag::note_also_found) 244233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar << Methods[I]->getSourceRange(); 244333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar } 2444f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor } 2445f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor} 2446f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor 24473fe104154dd2e8ffb351142d74f308938b5c99bfFariborz JahanianObjCMethodDecl *Sema::LookupImplementedMethodInGlobalPool(Selector Sel) { 2448db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl GlobalMethodPool::iterator Pos = MethodPool.find(Sel); 2449db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl if (Pos == MethodPool.end()) 24506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2451db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl 2452db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl GlobalMethods &Methods = Pos->second; 2453651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const ObjCMethodList *Method = &Methods.first; Method; 2454651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Method = Method->getNext()) 24550e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (Method->getMethod() && 24560e2c34f92f00628d48968dfea096d36381f494cbStephen Hines (Method->getMethod()->isDefined() || 24570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Method->getMethod()->isPropertyAccessor())) 24580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return Method->getMethod(); 2459651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2460651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const ObjCMethodList *Method = &Methods.second; Method; 2461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Method = Method->getNext()) 24620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (Method->getMethod() && 24630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines (Method->getMethod()->isDefined() || 24640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Method->getMethod()->isPropertyAccessor())) 24650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return Method->getMethod(); 24666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 24673fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian} 24683fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian 2469f98c688968777214bfff7a6cc9bbd4ff78e9c1d3Fariborz Jahanianstatic void 24709464a08a743295d6aefaca1a751b5b4d371cf99cFariborz JahanianHelperSelectorsForTypoCorrection( 24719464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian SmallVectorImpl<const ObjCMethodDecl *> &BestMethod, 24729464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian StringRef Typo, const ObjCMethodDecl * Method) { 24739464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian const unsigned MaxEditDistance = 1; 24749464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian unsigned BestEditDistance = MaxEditDistance + 1; 24754fe9644dc3533e4517f980645957c6fc9408c6f6Richard Trieu std::string MethodName = Method->getSelector().getAsString(); 24769464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian 24779464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian unsigned MinPossibleEditDistance = abs((int)MethodName.size() - (int)Typo.size()); 24789464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian if (MinPossibleEditDistance > 0 && 24799464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian Typo.size() / MinPossibleEditDistance < 1) 24809464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian return; 24819464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian unsigned EditDistance = Typo.edit_distance(MethodName, true, MaxEditDistance); 24829464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian if (EditDistance > MaxEditDistance) 24839464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian return; 24849464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian if (EditDistance == BestEditDistance) 24859464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian BestMethod.push_back(Method); 24869464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian else if (EditDistance < BestEditDistance) { 24879464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian BestMethod.clear(); 24889464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian BestMethod.push_back(Method); 24899464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian } 24909464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian} 24919464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian 2492d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanianstatic bool HelperIsMethodInObjCType(Sema &S, Selector Sel, 2493d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian QualType ObjectType) { 2494d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian if (ObjectType.isNull()) 2495d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian return true; 2496d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian if (S.LookupMethodInObjectType(Sel, ObjectType, true/*Instance method*/)) 2497d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian return true; 24986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return S.LookupMethodInObjectType(Sel, ObjectType, false/*Class method*/) != 24996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr; 2500d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian} 2501d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian 25029464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanianconst ObjCMethodDecl * 2503d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz JahanianSema::SelectorsForTypoCorrection(Selector Sel, 2504d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian QualType ObjectType) { 25059464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian unsigned NumArgs = Sel.getNumArgs(); 25069464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian SmallVector<const ObjCMethodDecl *, 8> Methods; 2507419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian bool ObjectIsId = true, ObjectIsClass = true; 2508419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian if (ObjectType.isNull()) 2509419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian ObjectIsId = ObjectIsClass = false; 2510419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian else if (!ObjectType->isObjCObjectPointerType()) 25116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2512419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian else if (const ObjCObjectPointerType *ObjCPtr = 2513419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian ObjectType->getAsObjCInterfacePointerType()) { 2514419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian ObjectType = QualType(ObjCPtr->getInterfaceType(), 0); 2515419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian ObjectIsId = ObjectIsClass = false; 2516419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian } 2517419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian else if (ObjectType->isObjCIdType() || ObjectType->isObjCQualifiedIdType()) 2518419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian ObjectIsClass = false; 2519419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian else if (ObjectType->isObjCClassType() || ObjectType->isObjCQualifiedClassType()) 2520419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian ObjectIsId = false; 2521419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian else 25226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 25236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 25249464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian for (GlobalMethodPool::iterator b = MethodPool.begin(), 25259464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian e = MethodPool.end(); b != e; b++) { 25269464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian // instance methods 25279464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian for (ObjCMethodList *M = &b->second.first; M; M=M->getNext()) 25280e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (M->getMethod() && 25290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines (M->getMethod()->getSelector().getNumArgs() == NumArgs) && 25300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines (M->getMethod()->getSelector() != Sel)) { 2531419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian if (ObjectIsId) 25320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Methods.push_back(M->getMethod()); 2533419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian else if (!ObjectIsClass && 25340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines HelperIsMethodInObjCType(*this, M->getMethod()->getSelector(), 25350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ObjectType)) 25360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Methods.push_back(M->getMethod()); 2537419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian } 25389464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian // class methods 25399464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian for (ObjCMethodList *M = &b->second.second; M; M=M->getNext()) 25400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (M->getMethod() && 25410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines (M->getMethod()->getSelector().getNumArgs() == NumArgs) && 25420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines (M->getMethod()->getSelector() != Sel)) { 2543419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian if (ObjectIsClass) 25440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Methods.push_back(M->getMethod()); 2545419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian else if (!ObjectIsId && 25460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines HelperIsMethodInObjCType(*this, M->getMethod()->getSelector(), 25470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ObjectType)) 25480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Methods.push_back(M->getMethod()); 2549419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian } 25509464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian } 25519464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian 25529464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian SmallVector<const ObjCMethodDecl *, 8> SelectedMethods; 25539464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian for (unsigned i = 0, e = Methods.size(); i < e; i++) { 25549464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian HelperSelectorsForTypoCorrection(SelectedMethods, 25559464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian Sel.getAsString(), Methods[i]); 25569464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian } 25576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return (SelectedMethods.size() == 1) ? SelectedMethods[0] : nullptr; 25589464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian} 25599464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian 2560f98c688968777214bfff7a6cc9bbd4ff78e9c1d3Fariborz Jahanian/// DiagnoseDuplicateIvars - 2561f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian/// Check for duplicate ivars in the entire class at the start of 25621dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// \@implementation. This becomes necesssary because class extension can 2563f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian/// add ivars to a class in random order which will not be known until 25641dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// class's \@implementation is seen. 2565f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanianvoid Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, 2566f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian ObjCInterfaceDecl *SID) { 2567651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *Ivar : ID->ivars()) { 2568f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian if (Ivar->isInvalidDecl()) 2569f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian continue; 2570f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian if (IdentifierInfo *II = Ivar->getIdentifier()) { 2571f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian ObjCIvarDecl* prevIvar = SID->lookupInstanceVariable(II); 2572f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian if (prevIvar) { 2573f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian Diag(Ivar->getLocation(), diag::err_duplicate_member) << II; 2574f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian Diag(prevIvar->getLocation(), diag::note_previous_declaration); 2575f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian Ivar->setInvalidDecl(); 2576f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian } 2577f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian } 2578f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian } 2579f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian} 2580f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian 2581d64251fd56577dd5c78903454632361e094c6dc1Erik VerbruggenSema::ObjCContainerKind Sema::getObjCContainerKind() const { 2582d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen switch (CurContext->getDeclKind()) { 2583d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen case Decl::ObjCInterface: 2584d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen return Sema::OCK_Interface; 2585d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen case Decl::ObjCProtocol: 2586d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen return Sema::OCK_Protocol; 2587d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen case Decl::ObjCCategory: 258833337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (cast<ObjCCategoryDecl>(CurContext)->IsClassExtension()) 2589d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen return Sema::OCK_ClassExtension; 259033337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar return Sema::OCK_Category; 2591d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen case Decl::ObjCImplementation: 2592d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen return Sema::OCK_Implementation; 2593d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen case Decl::ObjCCategoryImpl: 2594d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen return Sema::OCK_CategoryImplementation; 2595d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen 2596d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen default: 2597d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen return Sema::OCK_None; 2598d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen } 2599d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen} 2600d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen 2601a3c6246950f23d7d4cd748badaf8f05d7bc3f14aFariborz Jahanian// Note: For class/category implementations, allMethods is always null. 26020111e4da0133c7fb4815e5c60524d2aaddfbccf0Robert WilhelmDecl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods, 260380f8aca7aeac5be1c9c33813c2afcab6538199aaFariborz Jahanian ArrayRef<DeclGroupPtrTy> allTUVars) { 2604d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen if (getObjCContainerKind() == Sema::OCK_None) 26056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2606d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen 2607d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen assert(AtEnd.isValid() && "Invalid location for '@end'"); 2608a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian 2609a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext); 2610a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian Decl *ClassDecl = cast<Decl>(OCD); 261163e963cdffca9530f920dbab58b9b4eecb2a582cFariborz Jahanian 26121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool isInterfaceDeclKind = 2613f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl) 2614f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner || isa<ObjCProtocolDecl>(ClassDecl); 2615a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl); 261609c4719788a5cea09897525e528fa00420f1677bSteve Naroff 26170701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff // FIXME: Remove these and use the ObjCContainerDecl/DeclContext. 26180701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap; 26190701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap; 26200701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff 2621a3c6246950f23d7d4cd748badaf8f05d7bc3f14aFariborz Jahanian for (unsigned i = 0, e = allMethods.size(); i != e; i++ ) { 2622a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek ObjCMethodDecl *Method = 2623d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall cast_or_null<ObjCMethodDecl>(allMethods[i]); 26244d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 26254d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (!Method) continue; // Already issued a diagnostic. 2626f8d49f64ef6ab7e632717a31631fc289aab69428Douglas Gregor if (Method->isInstanceMethod()) { 26274d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner /// Check for instance method of the same name with incompatible types 2628a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek const ObjCMethodDecl *&PrevMethod = InsMap[Method->getSelector()]; 26291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod) 26304d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner : false; 26311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if ((isInterfaceDeclKind && PrevMethod && !match) 263282b4e768d38c12ceba7db23a96e8d845e00fdeb7Eli Friedman || (checkIdenticalMethods && match)) { 26335f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(Method->getLocation(), diag::err_duplicate_method_decl) 2634077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner << Method->getDeclName(); 26355f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(PrevMethod->getLocation(), diag::note_previous_declaration); 2636bdb2d5056fd675c27307b34efd371bbba6839e92Douglas Gregor Method->setInvalidDecl(); 26374d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } else { 26387209646add692c50503435bcffb13187a3349552Fariborz Jahanian if (PrevMethod) { 26393a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis Method->setAsRedeclaration(PrevMethod); 26407209646add692c50503435bcffb13187a3349552Fariborz Jahanian if (!Context.getSourceManager().isInSystemHeader( 26417209646add692c50503435bcffb13187a3349552Fariborz Jahanian Method->getLocation())) 26427209646add692c50503435bcffb13187a3349552Fariborz Jahanian Diag(Method->getLocation(), diag::warn_duplicate_method_decl) 26437209646add692c50503435bcffb13187a3349552Fariborz Jahanian << Method->getDeclName(); 26447209646add692c50503435bcffb13187a3349552Fariborz Jahanian Diag(PrevMethod->getLocation(), diag::note_previous_declaration); 26457209646add692c50503435bcffb13187a3349552Fariborz Jahanian } 26464d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner InsMap[Method->getSelector()] = Method; 26474d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner /// The following allows us to typecheck messages to "id". 2648ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor AddInstanceMethodToGlobalPool(Method); 26494d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 2650ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 26514d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner /// Check for class method of the same name with incompatible types 2652a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek const ObjCMethodDecl *&PrevMethod = ClsMap[Method->getSelector()]; 26531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod) 26544d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner : false; 26551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if ((isInterfaceDeclKind && PrevMethod && !match) 265682b4e768d38c12ceba7db23a96e8d845e00fdeb7Eli Friedman || (checkIdenticalMethods && match)) { 26575f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(Method->getLocation(), diag::err_duplicate_method_decl) 2658077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner << Method->getDeclName(); 26595f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(PrevMethod->getLocation(), diag::note_previous_declaration); 2660bdb2d5056fd675c27307b34efd371bbba6839e92Douglas Gregor Method->setInvalidDecl(); 26614d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } else { 26627209646add692c50503435bcffb13187a3349552Fariborz Jahanian if (PrevMethod) { 26633a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis Method->setAsRedeclaration(PrevMethod); 26647209646add692c50503435bcffb13187a3349552Fariborz Jahanian if (!Context.getSourceManager().isInSystemHeader( 26657209646add692c50503435bcffb13187a3349552Fariborz Jahanian Method->getLocation())) 26667209646add692c50503435bcffb13187a3349552Fariborz Jahanian Diag(Method->getLocation(), diag::warn_duplicate_method_decl) 26677209646add692c50503435bcffb13187a3349552Fariborz Jahanian << Method->getDeclName(); 26687209646add692c50503435bcffb13187a3349552Fariborz Jahanian Diag(PrevMethod->getLocation(), diag::note_previous_declaration); 26697209646add692c50503435bcffb13187a3349552Fariborz Jahanian } 26704d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner ClsMap[Method->getSelector()] = Method; 2671ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor AddFactoryMethodToGlobalPool(Method); 26724d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 26734d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 26744d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 2675b892d7010f9c2c61e2f3a2686546cbfbffbedef3Douglas Gregor if (isa<ObjCInterfaceDecl>(ClassDecl)) { 2676b892d7010f9c2c61e2f3a2686546cbfbffbedef3Douglas Gregor // Nothing to do here. 267709c4719788a5cea09897525e528fa00420f1677bSteve Naroff } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) { 267877e14bd3a714be42dbe1ab90a37b5832740b6df2Fariborz Jahanian // Categories are used to extend the class by declaring new methods. 26791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // By the same token, they are also used to add new properties. No 268077e14bd3a714be42dbe1ab90a37b5832740b6df2Fariborz Jahanian // need to compare the added property to those in the class. 2681b20ef3e3fbe0fabe213dc0149011e9f0d751a3a4Daniel Dunbar 268288f5e9be350f4b107f8665183a6d441874e0fcc7Fariborz Jahanian if (C->IsClassExtension()) { 268388f5e9be350f4b107f8665183a6d441874e0fcc7Fariborz Jahanian ObjCInterfaceDecl *CCPrimary = C->getClassInterface(); 268488f5e9be350f4b107f8665183a6d441874e0fcc7Fariborz Jahanian DiagnoseClassExtensionDupMethods(C, CCPrimary); 268588f5e9be350f4b107f8665183a6d441874e0fcc7Fariborz Jahanian } 26864d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 268709c4719788a5cea09897525e528fa00420f1677bSteve Naroff if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(ClassDecl)) { 268825760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian if (CDecl->getIdentifier()) 268925760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian // ProcessPropertyDecl is responsible for diagnosing conflicts with any 269025760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian // user-defined setter/getter. It also synthesizes setter/getter methods 269125760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian // and adds them to the DeclContext and global method pools. 2692651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *I : CDecl->properties()) 2693651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ProcessPropertyDecl(I, CDecl); 2694782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek CDecl->setAtEndRange(AtEnd); 269509c4719788a5cea09897525e528fa00420f1677bSteve Naroff } 269609c4719788a5cea09897525e528fa00420f1677bSteve Naroff if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) { 2697782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek IC->setAtEndRange(AtEnd); 26987ca8b0694840385d707689eba9ad965e7b28c8cbFariborz Jahanian if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) { 2699c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian // Any property declared in a class extension might have user 2700c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian // declared setter or getter in current class extension or one 2701c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian // of the other class extensions. Mark them as synthesized as 2702c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian // property will be synthesized when property with same name is 2703c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian // seen in the @implementation. 2704651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *Ext : IDecl->visible_extensions()) { 2705651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *Property : Ext->properties()) { 2706c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian // Skip over properties declared @dynamic 2707c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian if (const ObjCPropertyImplDecl *PIDecl 2708c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian = IC->FindPropertyImplDecl(Property->getIdentifier())) 2709c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian if (PIDecl->getPropertyImplementation() 2710c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian == ObjCPropertyImplDecl::Dynamic) 2711c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian continue; 2712d329724745b49f894b768d47275b7c2713106e89Douglas Gregor 2713651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *Ext : IDecl->visible_extensions()) { 2714d329724745b49f894b768d47275b7c2713106e89Douglas Gregor if (ObjCMethodDecl *GetterMethod 2715d329724745b49f894b768d47275b7c2713106e89Douglas Gregor = Ext->getInstanceMethod(Property->getGetterName())) 27161e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose GetterMethod->setPropertyAccessor(true); 2717c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian if (!Property->isReadOnly()) 2718d329724745b49f894b768d47275b7c2713106e89Douglas Gregor if (ObjCMethodDecl *SetterMethod 2719d329724745b49f894b768d47275b7c2713106e89Douglas Gregor = Ext->getInstanceMethod(Property->getSetterName())) 27201e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose SetterMethod->setPropertyAccessor(true); 2721d329724745b49f894b768d47275b7c2713106e89Douglas Gregor } 2722c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian } 2723c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian } 272417cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian ImplMethodsVsClassMethods(S, IC, IDecl); 27257ca8b0694840385d707689eba9ad965e7b28c8cbFariborz Jahanian AtomicPropertySetterGetterRules(IC, IDecl); 2726f85e193739c953358c865005855253af4f68a497John McCall DiagnoseOwningPropertyGetterSynthesis(IC); 2727651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DiagnoseUnusedBackingIvarInAccessor(S, IC); 2728651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (IDecl->hasDesignatedInitializers()) 2729651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DiagnoseMissingDesignatedInitOverrides(IC, IDecl); 2730651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2731b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard bool HasRootClassAttr = IDecl->hasAttr<ObjCRootClassAttr>(); 27326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (IDecl->getSuperClass() == nullptr) { 2733b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard // This class has no superclass, so check that it has been marked with 2734b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard // __attribute((objc_root_class)). 2735b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard if (!HasRootClassAttr) { 2736b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard SourceLocation DeclLoc(IDecl->getLocation()); 27376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceLocation SuperClassLoc(getLocForEndOfToken(DeclLoc)); 2738b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard Diag(DeclLoc, diag::warn_objc_root_class_missing) 2739b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard << IDecl->getIdentifier(); 2740b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard // See if NSObject is in the current scope, and if it is, suggest 2741b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard // adding " : NSObject " to the class declaration. 2742b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard NamedDecl *IF = LookupSingleName(TUScope, 2743b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject), 2744b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard DeclLoc, LookupOrdinaryName); 2745b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard ObjCInterfaceDecl *NSObjectDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF); 2746b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard if (NSObjectDecl && NSObjectDecl->getDefinition()) { 2747b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard Diag(SuperClassLoc, diag::note_objc_needs_superclass) 2748b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard << FixItHint::CreateInsertion(SuperClassLoc, " : NSObject "); 2749b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } else { 2750b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard Diag(SuperClassLoc, diag::note_objc_needs_superclass); 2751b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } 2752b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } 2753b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } else if (HasRootClassAttr) { 2754b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard // Complain that only root classes may have this attribute. 2755b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard Diag(IDecl->getLocation(), diag::err_objc_root_class_subclass); 2756b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } 2757b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard 2758260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (LangOpts.ObjCRuntime.isNonFragile()) { 2759f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian while (IDecl->getSuperClass()) { 2760f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass()); 2761f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian IDecl = IDecl->getSuperClass(); 2762f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian } 2763b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } 27647ca8b0694840385d707689eba9ad965e7b28c8cbFariborz Jahanian } 2765e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian SetIvarInitializers(IC); 27661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } else if (ObjCCategoryImplDecl* CatImplClass = 276709c4719788a5cea09897525e528fa00420f1677bSteve Naroff dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) { 2768782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek CatImplClass->setAtEndRange(AtEnd); 27691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27704d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Find category interface decl and then check that all methods declared 2771b20ef3e3fbe0fabe213dc0149011e9f0d751a3a4Daniel Dunbar // in this interface are implemented in the category @implementation. 277297a588715d6c896158106d6ca732196d3fee857bChris Lattner if (ObjCInterfaceDecl* IDecl = CatImplClass->getClassInterface()) { 2773d329724745b49f894b768d47275b7c2713106e89Douglas Gregor if (ObjCCategoryDecl *Cat 2774d329724745b49f894b768d47275b7c2713106e89Douglas Gregor = IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier())) { 2775d329724745b49f894b768d47275b7c2713106e89Douglas Gregor ImplMethodsVsClassMethods(S, CatImplClass, Cat); 27764d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 27774d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 27784d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 2779682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner if (isInterfaceDeclKind) { 2780682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner // Reject invalid vardecls. 2781a3c6246950f23d7d4cd748badaf8f05d7bc3f14aFariborz Jahanian for (unsigned i = 0, e = allTUVars.size(); i != e; i++) { 278218062394db459158942ab491a88b9d52a5c0ab0dSerge Pavlov DeclGroupRef DG = allTUVars[i].get(); 2783682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) 2784682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner if (VarDecl *VDecl = dyn_cast<VarDecl>(*I)) { 27855466c7b0ca8ce662e2c0bc295cecba2b78d6957dDaniel Dunbar if (!VDecl->hasExternalStorage()) 278687454161a6377b573d4fc3ff45e7b3ec193e860cSteve Naroff Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass); 2787b31cb7f1752ea011fd06ac9574ce24667d11cbdbFariborz Jahanian } 2788682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner } 278938e24c782c17b6058bf61d635747bbde19fb1bc7Fariborz Jahanian } 279010af87932fe4bffad539b24d512a33a1803daeaeFariborz Jahanian ActOnObjCContainerFinishDefinition(); 2791b4a686df4de21ec4eeca69211b21f7fe716abeaeArgyrios Kyrtzidis 2792a3c6246950f23d7d4cd748badaf8f05d7bc3f14aFariborz Jahanian for (unsigned i = 0, e = allTUVars.size(); i != e; i++) { 279318062394db459158942ab491a88b9d52a5c0ab0dSerge Pavlov DeclGroupRef DG = allTUVars[i].get(); 2794c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) 2795c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis (*I)->setTopLevelDeclInObjCContainer(); 2796b4a686df4de21ec4eeca69211b21f7fe716abeaeArgyrios Kyrtzidis Consumer.HandleTopLevelDeclInObjCContainer(DG); 2797b4a686df4de21ec4eeca69211b21f7fe716abeaeArgyrios Kyrtzidis } 2798d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen 2799abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko ActOnDocumentableDecl(ClassDecl); 2800d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen return ClassDecl; 28014d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 28024d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 28034d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 28044d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// CvtQTToAstBitMask - utility routine to produce an AST bitmask for 28054d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// objective-c's type qualifier from the parser version of the same info. 28061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic Decl::ObjCDeclQualifier 2807a526c5c67e5a0473c340903ee542ce570119665fTed KremenekCvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) { 280809e2c524a18435211cfbc2fb355f91e1ac43ea89John McCall return (Decl::ObjCDeclQualifier) (unsigned) PQTVal; 28094d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 28104d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 2811926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor/// \brief Check whether the declared result type of the given Objective-C 2812926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor/// method declaration is compatible with the method's class. 2813926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor/// 2814e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidisstatic Sema::ResultTypeCompatibilityKind 2815926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas GregorCheckRelatedResultTypeCompatibility(Sema &S, ObjCMethodDecl *Method, 2816926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor ObjCInterfaceDecl *CurrentClass) { 2817651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType ResultType = Method->getReturnType(); 2818651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2819926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // If an Objective-C method inherits its related result type, then its 2820926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // declared result type must be compatible with its own class type. The 2821926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // declared result type is compatible if: 2822926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (const ObjCObjectPointerType *ResultObjectType 2823926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor = ResultType->getAs<ObjCObjectPointerType>()) { 2824926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // - it is id or qualified id, or 2825926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (ResultObjectType->isObjCIdType() || 2826926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor ResultObjectType->isObjCQualifiedIdType()) 2827e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis return Sema::RTC_Compatible; 2828926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 2829926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (CurrentClass) { 2830926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (ObjCInterfaceDecl *ResultClass 2831926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor = ResultObjectType->getInterfaceDecl()) { 2832926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // - it is the same as the method's class type, or 283360ef308e51c71b760d7f598c1b763ceb7b768148Douglas Gregor if (declaresSameEntity(CurrentClass, ResultClass)) 2834e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis return Sema::RTC_Compatible; 2835926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 2836926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // - it is a superclass of the method's class type 2837926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (ResultClass->isSuperClassOf(CurrentClass)) 2838e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis return Sema::RTC_Compatible; 2839926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 2840e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor } else { 2841e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor // Any Objective-C pointer type might be acceptable for a protocol 2842e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor // method; we just don't know. 2843e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis return Sema::RTC_Unknown; 2844926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 2845926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 2846926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 2847e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis return Sema::RTC_Incompatible; 2848926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor} 2849926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 28506c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCallnamespace { 28516c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall/// A helper class for searching for methods which a particular method 28526c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall/// overrides. 28536c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCallclass OverrideSearch { 2854b732fcebcf2ce5c24a29d660e9400d7dc9f86b69Daniel Dunbarpublic: 28556c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall Sema &S; 28566c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall ObjCMethodDecl *Method; 2857b732fcebcf2ce5c24a29d660e9400d7dc9f86b69Daniel Dunbar llvm::SmallPtrSet<ObjCMethodDecl*, 4> Overridden; 28586c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall bool Recursive; 28596c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 28606c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCallpublic: 28616c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall OverrideSearch(Sema &S, ObjCMethodDecl *method) : S(S), Method(method) { 28626c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall Selector selector = method->getSelector(); 28636c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 28646c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // Bypass this search if we've never seen an instance/class method 28656c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // with this selector before. 28666c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall Sema::GlobalMethodPool::iterator it = S.MethodPool.find(selector); 28676c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall if (it == S.MethodPool.end()) { 28680ec56b7add7be643f490ea9b430823570f01b4e2Axel Naumann if (!S.getExternalSource()) return; 28695ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor S.ReadMethodPool(selector); 28705ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor 28715ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor it = S.MethodPool.find(selector); 28725ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor if (it == S.MethodPool.end()) 28735ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor return; 28746c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 28756c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall ObjCMethodList &list = 28766c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall method->isInstanceMethod() ? it->second.first : it->second.second; 28770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (!list.getMethod()) return; 28786c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 28796c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall ObjCContainerDecl *container 28806c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall = cast<ObjCContainerDecl>(method->getDeclContext()); 28816c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 28826c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // Prevent the search from reaching this container again. This is 28836c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // important with categories, which override methods from the 28846c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // interface and each other. 2885c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(container)) { 2886c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor searchFromContainer(container); 2887dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor if (ObjCInterfaceDecl *Interface = Category->getClassInterface()) 2888dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor searchFromContainer(Interface); 2889c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor } else { 2890c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor searchFromContainer(container); 2891c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor } 2892926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 28936c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 2894b732fcebcf2ce5c24a29d660e9400d7dc9f86b69Daniel Dunbar typedef llvm::SmallPtrSet<ObjCMethodDecl*, 128>::iterator iterator; 28956c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall iterator begin() const { return Overridden.begin(); } 28966c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall iterator end() const { return Overridden.end(); } 28976c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 28986c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCallprivate: 28996c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall void searchFromContainer(ObjCContainerDecl *container) { 29006c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall if (container->isInvalidDecl()) return; 29016c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 29026c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall switch (container->getDeclKind()) { 29036c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall#define OBJCCONTAINER(type, base) \ 29046c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall case Decl::type: \ 29056c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall searchFrom(cast<type##Decl>(container)); \ 29066c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall break; 29076c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall#define ABSTRACT_DECL(expansion) 29086c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall#define DECL(type, base) \ 29096c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall case Decl::type: 29106c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall#include "clang/AST/DeclNodes.inc" 29116c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall llvm_unreachable("not an ObjC container!"); 29126c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 29136c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 29146c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 29156c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall void searchFrom(ObjCProtocolDecl *protocol) { 29165e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor if (!protocol->hasDefinition()) 29175e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor return; 29185e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor 29196c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // A method in a protocol declaration overrides declarations from 29206c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // referenced ("parent") protocols. 29216c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall search(protocol->getReferencedProtocols()); 29226c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 29236c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 29246c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall void searchFrom(ObjCCategoryDecl *category) { 29256c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // A method in a category declaration overrides declarations from 29266c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // the main class and from protocols the category references. 2927c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor // The main class is handled in the constructor. 29286c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall search(category->getReferencedProtocols()); 29296c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 29306c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 29316c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall void searchFrom(ObjCCategoryImplDecl *impl) { 29326c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // A method in a category definition that has a category 29336c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // declaration overrides declarations from the category 29346c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // declaration. 29356c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall if (ObjCCategoryDecl *category = impl->getCategoryDecl()) { 29366c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall search(category); 2937dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor if (ObjCInterfaceDecl *Interface = category->getClassInterface()) 2938dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor search(Interface); 29396c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 29406c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // Otherwise it overrides declarations from the class. 2941dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor } else if (ObjCInterfaceDecl *Interface = impl->getClassInterface()) { 2942dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor search(Interface); 29436c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 29446c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 29456c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 29466c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall void searchFrom(ObjCInterfaceDecl *iface) { 29476c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // A method in a class declaration overrides declarations from 29482e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor if (!iface->hasDefinition()) 29492e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor return; 29502e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor 29516c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // - categories, 2952651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *Cat : iface->known_categories()) 2953651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines search(Cat); 29546c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 29556c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // - the super class, and 29566c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall if (ObjCInterfaceDecl *super = iface->getSuperClass()) 29576c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall search(super); 29586c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 29596c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // - any referenced protocols. 29606c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall search(iface->getReferencedProtocols()); 29616c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 29626c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 29636c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall void searchFrom(ObjCImplementationDecl *impl) { 29646c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // A method in a class implementation overrides declarations from 29656c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // the class interface. 2966dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor if (ObjCInterfaceDecl *Interface = impl->getClassInterface()) 2967dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor search(Interface); 29686c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 29696c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 29706c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 29716c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall void search(const ObjCProtocolList &protocols) { 29726c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall for (ObjCProtocolList::iterator i = protocols.begin(), e = protocols.end(); 29736c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall i != e; ++i) 29746c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall search(*i); 29756c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 29766c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 29776c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall void search(ObjCContainerDecl *container) { 29786c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // Check for a method in this container which matches this selector. 29796c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall ObjCMethodDecl *meth = container->getMethod(Method->getSelector(), 298004593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis Method->isInstanceMethod(), 298104593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis /*AllowHidden=*/true); 29826c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 29836c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // If we find one, record it and bail out. 29846c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall if (meth) { 29856c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall Overridden.insert(meth); 29866c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall return; 29876c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 29886c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 29896c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // Otherwise, search for methods that a hypothetical method here 29906c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // would have overridden. 29916c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 29926c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // Note that we're now in a recursive case. 29936c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall Recursive = true; 29946c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 29956c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall searchFromContainer(container); 29966c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 29976c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall}; 2998926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor} 2999926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 3000e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidisvoid Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, 3001e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis ObjCInterfaceDecl *CurrentClass, 3002e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis ResultTypeCompatibilityKind RTC) { 3003e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // Search for overridden methods and merge information down from them. 3004e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis OverrideSearch overrides(*this, ObjCMethod); 3005e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // Keep track if the method overrides any method in the class's base classes, 3006e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // its protocols, or its categories' protocols; we will keep that info 3007e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // in the ObjCMethodDecl. 3008e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // For this info, a method in an implementation is not considered as 3009e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // overriding the same method in the interface or its categories. 3010e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis bool hasOverriddenMethodsInBaseOrProtocol = false; 3011e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis for (OverrideSearch::iterator 3012e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis i = overrides.begin(), e = overrides.end(); i != e; ++i) { 3013e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis ObjCMethodDecl *overridden = *i; 3014e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 3015e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis if (!hasOverriddenMethodsInBaseOrProtocol) { 3016e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis if (isa<ObjCProtocolDecl>(overridden->getDeclContext()) || 3017e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis CurrentClass != overridden->getClassInterface() || 3018e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis overridden->isOverriding()) { 3019e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis hasOverriddenMethodsInBaseOrProtocol = true; 3020e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis 3021e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis } else if (isa<ObjCImplDecl>(ObjCMethod->getDeclContext())) { 3022e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // OverrideSearch will return as "overridden" the same method in the 3023e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // interface. For hasOverriddenMethodsInBaseOrProtocol, we need to 3024e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // check whether a category of a base class introduced a method with the 3025e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // same selector, after the interface method declaration. 3026e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // To avoid unnecessary lookups in the majority of cases, we use the 3027e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // extra info bits in GlobalMethodPool to check whether there were any 3028e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // category methods with this selector. 3029e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis GlobalMethodPool::iterator It = 3030e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis MethodPool.find(ObjCMethod->getSelector()); 3031e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis if (It != MethodPool.end()) { 3032e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis ObjCMethodList &List = 3033e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis ObjCMethod->isInstanceMethod()? It->second.first: It->second.second; 3034e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis unsigned CategCount = List.getBits(); 3035e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis if (CategCount > 0) { 3036e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // If the method is in a category we'll do lookup if there were at 3037e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // least 2 category methods recorded, otherwise only one will do. 3038e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis if (CategCount > 1 || 3039e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis !isa<ObjCCategoryImplDecl>(overridden->getDeclContext())) { 3040e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis OverrideSearch overrides(*this, overridden); 3041e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis for (OverrideSearch::iterator 3042e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis OI= overrides.begin(), OE= overrides.end(); OI!=OE; ++OI) { 3043e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis ObjCMethodDecl *SuperOverridden = *OI; 3044ab3d509bc45218c278454962ff644bb13d18ce1aArgyrios Kyrtzidis if (isa<ObjCProtocolDecl>(SuperOverridden->getDeclContext()) || 3045ab3d509bc45218c278454962ff644bb13d18ce1aArgyrios Kyrtzidis CurrentClass != SuperOverridden->getClassInterface()) { 3046e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis hasOverriddenMethodsInBaseOrProtocol = true; 3047e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis overridden->setOverriding(true); 3048e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis break; 3049e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis } 3050e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis } 3051e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis } 3052e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis } 3053e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis } 3054e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis } 3055e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis } 3056e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 3057e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // Propagate down the 'related result type' bit from overridden methods. 3058e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis if (RTC != Sema::RTC_Incompatible && overridden->hasRelatedResultType()) 3059e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis ObjCMethod->SetRelatedResultType(); 3060e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 3061e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // Then merge the declarations. 3062e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis mergeObjCMethodDecls(ObjCMethod, overridden); 3063e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 3064e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis if (ObjCMethod->isImplicit() && overridden->isImplicit()) 3065e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis continue; // Conflicting properties are detected elsewhere. 3066e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 3067e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // Check for overriding methods 3068e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis if (isa<ObjCInterfaceDecl>(ObjCMethod->getDeclContext()) || 3069e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis isa<ObjCImplementationDecl>(ObjCMethod->getDeclContext())) 3070e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis CheckConflictingOverridingMethod(ObjCMethod, overridden, 3071e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis isa<ObjCProtocolDecl>(overridden->getDeclContext())); 3072e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 3073e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis if (CurrentClass && overridden->getDeclContext() != CurrentClass && 3074c4133a477389dacb4479a96ee2227b92aea0a237Fariborz Jahanian isa<ObjCInterfaceDecl>(overridden->getDeclContext()) && 3075c4133a477389dacb4479a96ee2227b92aea0a237Fariborz Jahanian !overridden->isImplicit() /* not meant for properties */) { 3076e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis ObjCMethodDecl::param_iterator ParamI = ObjCMethod->param_begin(), 3077e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis E = ObjCMethod->param_end(); 30780a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor ObjCMethodDecl::param_iterator PrevI = overridden->param_begin(), 30790a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor PrevE = overridden->param_end(); 30800a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor for (; ParamI != E && PrevI != PrevE; ++ParamI, ++PrevI) { 3081e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis assert(PrevI != overridden->param_end() && "Param mismatch"); 3082e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis QualType T1 = Context.getCanonicalType((*ParamI)->getType()); 3083e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis QualType T2 = Context.getCanonicalType((*PrevI)->getType()); 3084e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // If type of argument of method in this class does not match its 3085e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // respective argument type in the super class method, issue warning; 3086e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis if (!Context.typesAreCompatible(T1, T2)) { 3087e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis Diag((*ParamI)->getLocation(), diag::ext_typecheck_base_super) 3088e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis << T1 << T2; 3089e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis Diag(overridden->getLocation(), diag::note_previous_declaration); 3090e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis break; 3091e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis } 3092e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis } 3093e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis } 3094e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis } 3095e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 3096e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis ObjCMethod->setOverriding(hasOverriddenMethodsInBaseOrProtocol); 3097e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis} 3098e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 3099d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema::ActOnMethodDeclaration( 31007f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian Scope *S, 31014d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner SourceLocation MethodLoc, SourceLocation EndLoc, 3102a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian tok::TokenKind MethodType, 3103b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ObjCDeclSpec &ReturnQT, ParsedType ReturnType, 310411d77169555480ee0a04c6e5bc390d8fde41175dArgyrios Kyrtzidis ArrayRef<SourceLocation> SelectorLocs, 31054d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner Selector Sel, 31064d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // optional arguments. The number of types/arguments is obtained 31074d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // from the Sel.getNumArgs(). 3108e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner ObjCArgInfo *ArgInfo, 31094f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args 31104d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind, 311190ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian bool isVariadic, bool MethodDefinition) { 3112da323adbb99cee19a203ead852d5d9bfebb23fb7Steve Naroff // Make sure we can establish a context for the method. 3113a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian if (!CurContext->isObjCContainer()) { 3114da323adbb99cee19a203ead852d5d9bfebb23fb7Steve Naroff Diag(MethodLoc, diag::error_missing_method_context); 31156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 3116da323adbb99cee19a203ead852d5d9bfebb23fb7Steve Naroff } 3117a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext); 3118a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian Decl *ClassDecl = cast<Decl>(OCD); 31190ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner QualType resultDeclType; 31201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3121e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor bool HasRelatedResultType = false; 31226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TypeSourceInfo *ReturnTInfo = nullptr; 3123ccef371a67756233aa97770e4fccdfa868b3e2d0Steve Naroff if (ReturnType) { 3124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines resultDeclType = GetTypeFromParser(ReturnType, &ReturnTInfo); 31251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3126ddb5a3926d715ab4354ca36117679e3f4d5d3e21Eli Friedman if (CheckFunctionReturnType(resultDeclType, MethodLoc)) 31276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 3128ddb5a3926d715ab4354ca36117679e3f4d5d3e21Eli Friedman 3129e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor HasRelatedResultType = (resultDeclType == Context.getObjCInstanceType()); 3130aab24a616de59c543d78d7636f22fb786053fefaFariborz Jahanian } else { // get the type for "id". 31310ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner resultDeclType = Context.getObjCIdType(); 3132feb4fa165c5e8c40ffc8b1b655cc3c8071862b20Fariborz Jahanian Diag(MethodLoc, diag::warn_missing_method_return_type) 313311d77169555480ee0a04c6e5bc390d8fde41175dArgyrios Kyrtzidis << FixItHint::CreateInsertion(SelectorLocs.front(), "(id)"); 3134aab24a616de59c543d78d7636f22fb786053fefaFariborz Jahanian } 31351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCMethodDecl *ObjCMethod = ObjCMethodDecl::Create( 3137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Context, MethodLoc, EndLoc, Sel, resultDeclType, ReturnTInfo, CurContext, 3138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MethodType == tok::minus, isVariadic, 3139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /*isPropertyAccessor=*/false, 3140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /*isImplicitlyDeclared=*/false, /*isDefined=*/false, 3141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MethodDeclKind == tok::objc_optional ? ObjCMethodDecl::Optional 3142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : ObjCMethodDecl::Required, 3143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HasRelatedResultType); 31441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 31455f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<ParmVarDecl*, 16> Params; 31461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 31477db638d1222bfb2517ac54388e83169a4c76cf7eChris Lattner for (unsigned i = 0, e = Sel.getNumArgs(); i != e; ++i) { 314858e4677a948e80c92deeebbcd3bdd9266adda798John McCall QualType ArgType; 3149a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TypeSourceInfo *DI; 31501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 31517247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie if (!ArgInfo[i].Type) { 315258e4677a948e80c92deeebbcd3bdd9266adda798John McCall ArgType = Context.getObjCIdType(); 31536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines DI = nullptr; 3154e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner } else { 315558e4677a948e80c92deeebbcd3bdd9266adda798John McCall ArgType = GetTypeFromParser(ArgInfo[i].Type, &DI); 3156e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner } 31571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 31587f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian LookupResult R(*this, ArgInfo[i].Name, ArgInfo[i].NameLoc, 31597f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian LookupOrdinaryName, ForRedeclaration); 31607f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian LookupName(R, S); 31617f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian if (R.isSingleResult()) { 31627f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian NamedDecl *PrevDecl = R.getFoundDecl(); 31637f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian if (S->isDeclScope(PrevDecl)) { 316490ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian Diag(ArgInfo[i].NameLoc, 316590ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian (MethodDefinition ? diag::warn_method_param_redefinition 316690ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian : diag::warn_method_param_declaration)) 31677f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian << ArgInfo[i].Name; 31687f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian Diag(PrevDecl->getLocation(), 31697f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian diag::note_previous_declaration); 31707f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian } 31717f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian } 31727f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian 3173ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara SourceLocation StartLoc = DI 3174ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara ? DI->getTypeLoc().getBeginLoc() 3175ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara : ArgInfo[i].NameLoc; 3176ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara 317781ef3e664d8ae250fbb68b2b6ccdeebb6c13ede5John McCall ParmVarDecl* Param = CheckParameter(ObjCMethod, StartLoc, 317881ef3e664d8ae250fbb68b2b6ccdeebb6c13ede5John McCall ArgInfo[i].NameLoc, ArgInfo[i].Name, 3179d2615cc53b916e8aae45783ca7113b93de515ce3Rafael Espindola ArgType, DI, SC_None); 31801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 31817079886ab5a9df450ed773419f0ae81f8404e2aaJohn McCall Param->setObjCMethodScopeInfo(i); 31827079886ab5a9df450ed773419f0ae81f8404e2aaJohn McCall 3183a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek Param->setObjCDeclQualifier( 3184e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier())); 31851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3186f97e8fa2966e3e49eac433336450f24ccbdf8b4aChris Lattner // Apply the attributes to the parameter. 31879cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs); 31881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 318947b1d96bde79633d4aeded1cde2c5f870a58af24Fariborz Jahanian if (Param->hasAttr<BlocksAttr>()) { 319047b1d96bde79633d4aeded1cde2c5f870a58af24Fariborz Jahanian Diag(Param->getLocation(), diag::err_block_on_nonlocal); 319147b1d96bde79633d4aeded1cde2c5f870a58af24Fariborz Jahanian Param->setInvalidDecl(); 319247b1d96bde79633d4aeded1cde2c5f870a58af24Fariborz Jahanian } 31937f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian S->AddDecl(Param); 31947f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian IdResolver.AddDecl(Param); 31957f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian 31964d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner Params.push_back(Param); 31974d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 31987f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian 31994f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian for (unsigned i = 0, e = CNumArgs; i != e; ++i) { 3200d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall ParmVarDecl *Param = cast<ParmVarDecl>(CParamInfo[i].Param); 32014f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian QualType ArgType = Param->getType(); 32024f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian if (ArgType.isNull()) 32034f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian ArgType = Context.getObjCIdType(); 32044f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian else 32054f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian // Perform the default array/function conversions (C99 6.7.5.3p[7,8]). 320679e6bd379773447a74cc3e579d9081e4c5cb6d63Douglas Gregor ArgType = Context.getAdjustedParameterType(ArgType); 3207ddb5a3926d715ab4354ca36117679e3f4d5d3e21Eli Friedman 32084f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian Param->setDeclContext(ObjCMethod); 32094f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian Params.push_back(Param); 32104f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian } 32114f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian 3212491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis ObjCMethod->setMethodParams(Context, Params, SelectorLocs); 3213a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek ObjCMethod->setObjCDeclQualifier( 3214a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier())); 32153568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 32163568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (AttrList) 32179cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList); 32181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3219bdb2d5056fd675c27307b34efd371bbba6839e92Douglas Gregor // Add the method now. 32206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const ObjCMethodDecl *PrevMethod = nullptr; 32216c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall if (ObjCImplDecl *ImpDecl = dyn_cast<ObjCImplDecl>(ClassDecl)) { 32224d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (MethodType == tok::minus) { 322317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis PrevMethod = ImpDecl->getInstanceMethod(Sel); 322417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis ImpDecl->addInstanceMethod(ObjCMethod); 32254d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } else { 322617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis PrevMethod = ImpDecl->getClassMethod(Sel); 322717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis ImpDecl->addClassMethod(ObjCMethod); 32284d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 3229926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 32306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ObjCMethodDecl *IMD = nullptr; 32317fda400103a5ae21fdc5f31b07c69cf60737cb29Fariborz Jahanian if (ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface()) 32327fda400103a5ae21fdc5f31b07c69cf60737cb29Fariborz Jahanian IMD = IDecl->lookupMethod(ObjCMethod->getSelector(), 32337fda400103a5ae21fdc5f31b07c69cf60737cb29Fariborz Jahanian ObjCMethod->isInstanceMethod()); 323438b3bd8bf3c424e82b4dca0acaec84af28666656Fariborz Jahanian if (IMD && IMD->hasAttr<ObjCRequiresSuperAttr>() && 323538b3bd8bf3c424e82b4dca0acaec84af28666656Fariborz Jahanian !ObjCMethod->hasAttr<ObjCRequiresSuperAttr>()) { 323638b3bd8bf3c424e82b4dca0acaec84af28666656Fariborz Jahanian // merge the attribute into implementation. 3237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCMethod->addAttr(ObjCRequiresSuperAttr::CreateImplicit(Context, 3238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCMethod->getLocation())); 3239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 3240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (isa<ObjCCategoryImplDecl>(ImpDecl)) { 3241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCMethodFamily family = 3242651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCMethod->getSelector().getMethodFamily(); 3243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (family == OMF_dealloc && IMD && IMD->isOverriding()) 3244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diag(ObjCMethod->getLocation(), diag::warn_dealloc_in_category) 32453306ec1923973d7b5767b23ba95915af2fec87d7Ted Kremenek << ObjCMethod->getDeclName(); 3246ec236787c5868eef53a807ca1a68b6b0b8c604c6Fariborz Jahanian } 3247bdb2d5056fd675c27307b34efd371bbba6839e92Douglas Gregor } else { 3248bdb2d5056fd675c27307b34efd371bbba6839e92Douglas Gregor cast<DeclContext>(ClassDecl)->addDecl(ObjCMethod); 32494d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 32506c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 32514d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (PrevMethod) { 32524d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // You can never have two method definitions with the same name. 32535f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(ObjCMethod->getLocation(), diag::err_duplicate_method_decl) 3254077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner << ObjCMethod->getDeclName(); 32555f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(PrevMethod->getLocation(), diag::note_previous_declaration); 3256fbff0c4510c7f0e0f30a005960e434b973f5bd21Fariborz Jahanian ObjCMethod->setInvalidDecl(); 3257fbff0c4510c7f0e0f30a005960e434b973f5bd21Fariborz Jahanian return ObjCMethod; 32581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 325954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3260926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // If this Objective-C method does not have a related result type, but we 3261926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // are allowed to infer related result types, try to do so based on the 3262926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // method family. 3263926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor ObjCInterfaceDecl *CurrentClass = dyn_cast<ObjCInterfaceDecl>(ClassDecl); 3264926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (!CurrentClass) { 3265926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(ClassDecl)) 3266926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor CurrentClass = Cat->getClassInterface(); 3267926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor else if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(ClassDecl)) 3268926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor CurrentClass = Impl->getClassInterface(); 3269926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor else if (ObjCCategoryImplDecl *CatImpl 3270926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor = dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) 3271926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor CurrentClass = CatImpl->getClassInterface(); 3272926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 32736c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 3274e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor ResultTypeCompatibilityKind RTC 3275e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor = CheckRelatedResultTypeCompatibility(*this, ObjCMethod, CurrentClass); 32766c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 3277e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis CheckObjCMethodOverrides(ObjCMethod, CurrentClass, RTC); 32786c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 3279f85e193739c953358c865005855253af4f68a497John McCall bool ARCError = false; 32804e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjCAutoRefCount) 3281b846381fc3099b2340ba8c74d16178203a60d9a0John McCall ARCError = CheckARCMethodDecl(ObjCMethod); 3282f85e193739c953358c865005855253af4f68a497John McCall 3283e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor // Infer the related result type when possible. 3284e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis if (!ARCError && RTC == Sema::RTC_Compatible && 3285e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor !ObjCMethod->hasRelatedResultType() && 3286e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor LangOpts.ObjCInferRelatedResultType) { 3287926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor bool InferRelatedResultType = false; 3288926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor switch (ObjCMethod->getMethodFamily()) { 3289926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_None: 3290926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_copy: 3291926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_dealloc: 329280cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber case OMF_finalize: 3293926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_mutableCopy: 3294926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_release: 3295926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_retainCount: 3296176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case OMF_initialize: 32979670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian case OMF_performSelector: 3298926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor break; 3299926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 3300926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_alloc: 3301926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_new: 330233337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar InferRelatedResultType = ObjCMethod->isClassMethod(); 3303926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor break; 3304926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 3305926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_init: 3306926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_autorelease: 3307926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_retain: 3308926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_self: 3309926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor InferRelatedResultType = ObjCMethod->isInstanceMethod(); 3310926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor break; 3311926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 3312926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 331333337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar if (InferRelatedResultType && 331433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar !ObjCMethod->getReturnType()->isObjCIndependentClassType()) 3315926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor ObjCMethod->SetRelatedResultType(); 3316926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 3317a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 3318a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko ActOnDocumentableDecl(ObjCMethod); 3319a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 3320d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return ObjCMethod; 33214d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 33224d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 3323cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattnerbool Sema::CheckObjCDeclScope(Decl *D) { 332458a764940df0cd41767367eb2f4fced6f374176bFariborz Jahanian // Following is also an error. But it is caused by a missing @end 332558a764940df0cd41767367eb2f4fced6f374176bFariborz Jahanian // and diagnostic is issued elsewhere. 3326fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis if (isa<ObjCContainerDecl>(CurContext->getRedeclContext())) 3327fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis return false; 3328fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis 3329fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis // If we switched context to translation unit while we are still lexically in 3330fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis // an objc container, it means the parser missed emitting an error. 3331fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis if (isa<TranslationUnitDecl>(getCurLexicalContext()->getRedeclContext())) 3332a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian return false; 3333a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian 333415281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope); 333515281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson D->setInvalidDecl(); 33361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 333715281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson return true; 333815281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson} 3339cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner 33401dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// Called whenever \@defs(ClassName) is encountered in the source. Inserts the 3341cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner/// instance variables of ClassName into Decls. 3342d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Sema::ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, 3343cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner IdentifierInfo *ClassName, 33445f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<Decl*> &Decls) { 3345cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner // Check that ClassName is a valid class 3346c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor ObjCInterfaceDecl *Class = getObjCInterfaceDecl(ClassName, DeclStart); 3347cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner if (!Class) { 3348cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner Diag(DeclStart, diag::err_undef_interface) << ClassName; 3349cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner return; 3350cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner } 3351260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (LangOpts.ObjCRuntime.isNonFragile()) { 33520468fb99068c40990a3b1451938fee5b90daf941Fariborz Jahanian Diag(DeclStart, diag::err_atdef_nonfragile_interface); 33530468fb99068c40990a3b1451938fee5b90daf941Fariborz Jahanian return; 33540468fb99068c40990a3b1451938fee5b90daf941Fariborz Jahanian } 33551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3356cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner // Collect the instance variables 3357db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose SmallVector<const ObjCIvarDecl*, 32> Ivars; 33582c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian Context.DeepCollectObjCIvars(Class, true, Ivars); 33594183335fa8bfce8dd2d910dc992dace8c5f66b0dFariborz Jahanian // For each ivar, create a fresh ObjCAtDefsFieldDecl. 33602c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian for (unsigned i = 0; i < Ivars.size(); i++) { 3361db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const FieldDecl* ID = cast<FieldDecl>(Ivars[i]); 3362d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall RecordDecl *Record = dyn_cast<RecordDecl>(TagD); 3363ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara Decl *FD = ObjCAtDefsFieldDecl::Create(Context, Record, 3364ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara /*FIXME: StartL=*/ID->getLocation(), 3365ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara ID->getLocation(), 33664183335fa8bfce8dd2d910dc992dace8c5f66b0dFariborz Jahanian ID->getIdentifier(), ID->getType(), 33674183335fa8bfce8dd2d910dc992dace8c5f66b0dFariborz Jahanian ID->getBitWidth()); 3368d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decls.push_back(FD); 33694183335fa8bfce8dd2d910dc992dace8c5f66b0dFariborz Jahanian } 33701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3371cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner // Introduce all of these fields into the appropriate scope. 33725f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner for (SmallVectorImpl<Decl*>::iterator D = Decls.begin(); 3373cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner D != Decls.end(); ++D) { 3374d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall FieldDecl *FD = cast<FieldDecl>(*D); 33754e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus) 3376cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner PushOnScopeChains(cast<FieldDecl>(FD), S); 3377d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD)) 337817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis Record->addDecl(FD); 3379cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner } 3380cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner} 3381cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner 3382160b5630aa781ac348303e1ae088d27016637778Douglas Gregor/// \brief Build a type-check a new Objective-C exception variable declaration. 3383ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo BagnaraVarDecl *Sema::BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType T, 3384ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara SourceLocation StartLoc, 3385ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara SourceLocation IdLoc, 3386ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara IdentifierInfo *Id, 3387160b5630aa781ac348303e1ae088d27016637778Douglas Gregor bool Invalid) { 3388160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // ISO/IEC TR 18037 S6.7.3: "The type of an object with automatic storage 3389160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // duration shall not be qualified by an address-space qualifier." 3390160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // Since all parameters have automatic store duration, they can not have 3391160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // an address space. 3392160b5630aa781ac348303e1ae088d27016637778Douglas Gregor if (T.getAddressSpace() != 0) { 3393ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara Diag(IdLoc, diag::err_arg_with_address_space); 3394160b5630aa781ac348303e1ae088d27016637778Douglas Gregor Invalid = true; 3395160b5630aa781ac348303e1ae088d27016637778Douglas Gregor } 3396160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 3397160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // An @catch parameter must be an unqualified object pointer type; 3398160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // FIXME: Recover from "NSObject foo" by inserting the * in "NSObject *foo"? 3399160b5630aa781ac348303e1ae088d27016637778Douglas Gregor if (Invalid) { 3400160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // Don't do any further checking. 3401be270a0fae647ae3fb4d6a21ba1ea5ab9c40853aDouglas Gregor } else if (T->isDependentType()) { 3402be270a0fae647ae3fb4d6a21ba1ea5ab9c40853aDouglas Gregor // Okay: we don't know what this type will instantiate to. 3403160b5630aa781ac348303e1ae088d27016637778Douglas Gregor } else if (!T->isObjCObjectPointerType()) { 3404160b5630aa781ac348303e1ae088d27016637778Douglas Gregor Invalid = true; 3405ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara Diag(IdLoc ,diag::err_catch_param_not_objc_type); 3406160b5630aa781ac348303e1ae088d27016637778Douglas Gregor } else if (T->isObjCQualifiedIdType()) { 3407160b5630aa781ac348303e1ae088d27016637778Douglas Gregor Invalid = true; 3408ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara Diag(IdLoc, diag::err_illegal_qualifiers_on_catch_parm); 3409160b5630aa781ac348303e1ae088d27016637778Douglas Gregor } 3410160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 3411ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara VarDecl *New = VarDecl::Create(Context, CurContext, StartLoc, IdLoc, Id, 3412d2615cc53b916e8aae45783ca7113b93de515ce3Rafael Espindola T, TInfo, SC_None); 3413324b54d3f60d92a82815512119791ce1c285b63eDouglas Gregor New->setExceptionVariable(true); 3414324b54d3f60d92a82815512119791ce1c285b63eDouglas Gregor 34159aab9c4116bb3ea876d92d4af10bff7f4c451f24Douglas Gregor // In ARC, infer 'retaining' for variables of retainable type. 34164e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(New)) 34179aab9c4116bb3ea876d92d4af10bff7f4c451f24Douglas Gregor Invalid = true; 34189aab9c4116bb3ea876d92d4af10bff7f4c451f24Douglas Gregor 3419160b5630aa781ac348303e1ae088d27016637778Douglas Gregor if (Invalid) 3420160b5630aa781ac348303e1ae088d27016637778Douglas Gregor New->setInvalidDecl(); 3421160b5630aa781ac348303e1ae088d27016637778Douglas Gregor return New; 3422160b5630aa781ac348303e1ae088d27016637778Douglas Gregor} 3423160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 3424d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) { 3425160b5630aa781ac348303e1ae088d27016637778Douglas Gregor const DeclSpec &DS = D.getDeclSpec(); 3426160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 3427160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // We allow the "register" storage class on exception variables because 3428160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // GCC did, but we drop it completely. Any other storage class is an error. 3429160b5630aa781ac348303e1ae088d27016637778Douglas Gregor if (DS.getStorageClassSpec() == DeclSpec::SCS_register) { 3430160b5630aa781ac348303e1ae088d27016637778Douglas Gregor Diag(DS.getStorageClassSpecLoc(), diag::warn_register_objc_catch_parm) 3431160b5630aa781ac348303e1ae088d27016637778Douglas Gregor << FixItHint::CreateRemoval(SourceRange(DS.getStorageClassSpecLoc())); 3432ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith } else if (DeclSpec::SCS SCS = DS.getStorageClassSpec()) { 3433160b5630aa781ac348303e1ae088d27016637778Douglas Gregor Diag(DS.getStorageClassSpecLoc(), diag::err_storage_spec_on_catch_parm) 3434ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith << DeclSpec::getSpecifierName(SCS); 3435ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith } 3436ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec()) 3437ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), 3438ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith diag::err_invalid_thread) 3439ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith << DeclSpec::getSpecifierName(TSCS); 3440160b5630aa781ac348303e1ae088d27016637778Douglas Gregor D.getMutableDeclSpec().ClearStorageClassSpecs(); 3441160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 3442c7f811638f8603fa373d2be724e8b1c8ba51ad75Richard Smith DiagnoseFunctionSpecifiers(D.getDeclSpec()); 3443160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 3444160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // Check that there are no default arguments inside the type of this 3445160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // exception object (C++ only). 34464e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus) 3447160b5630aa781ac348303e1ae088d27016637778Douglas Gregor CheckExtraCXXDefaultArguments(D); 3448160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 34493215398dc9dac2be19a9fc1df929e6b7d83eafcaArgyrios Kyrtzidis TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 3450bf1a028246d884a540aeafa38e89be59a269b072John McCall QualType ExceptionType = TInfo->getType(); 3451160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 3452ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara VarDecl *New = BuildObjCExceptionDecl(TInfo, ExceptionType, 3453ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara D.getSourceRange().getBegin(), 3454ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara D.getIdentifierLoc(), 3455ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara D.getIdentifier(), 3456160b5630aa781ac348303e1ae088d27016637778Douglas Gregor D.isInvalidType()); 3457160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 3458160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // Parameter declarators cannot be qualified (C++ [dcl.meaning]p1). 3459160b5630aa781ac348303e1ae088d27016637778Douglas Gregor if (D.getCXXScopeSpec().isSet()) { 3460160b5630aa781ac348303e1ae088d27016637778Douglas Gregor Diag(D.getIdentifierLoc(), diag::err_qualified_objc_catch_parm) 3461160b5630aa781ac348303e1ae088d27016637778Douglas Gregor << D.getCXXScopeSpec().getRange(); 3462160b5630aa781ac348303e1ae088d27016637778Douglas Gregor New->setInvalidDecl(); 3463160b5630aa781ac348303e1ae088d27016637778Douglas Gregor } 3464160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 3465160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // Add the parameter declaration into this scope. 3466d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall S->AddDecl(New); 3467160b5630aa781ac348303e1ae088d27016637778Douglas Gregor if (D.getIdentifier()) 3468160b5630aa781ac348303e1ae088d27016637778Douglas Gregor IdResolver.AddDecl(New); 3469160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 3470160b5630aa781ac348303e1ae088d27016637778Douglas Gregor ProcessDeclAttributes(S, New, D); 3471160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 3472160b5630aa781ac348303e1ae088d27016637778Douglas Gregor if (New->hasAttr<BlocksAttr>()) 3473160b5630aa781ac348303e1ae088d27016637778Douglas Gregor Diag(New->getLocation(), diag::err_block_on_nonlocal); 3474d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return New; 34754e6c0d19b7c072758922cf80525a81aeefc6e64bDouglas Gregor} 3476786cd154f2a48d2b464679d33fcd5df0cd794c06Fariborz Jahanian 3477786cd154f2a48d2b464679d33fcd5df0cd794c06Fariborz Jahanian/// CollectIvarsToConstructOrDestruct - Collect those ivars which require 3478e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian/// initialization. 34792c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanianvoid Sema::CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, 34805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<ObjCIvarDecl*> &Ivars) { 34812c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian for (ObjCIvarDecl *Iv = OI->all_declared_ivar_begin(); Iv; 34822c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian Iv= Iv->getNextIvar()) { 3483786cd154f2a48d2b464679d33fcd5df0cd794c06Fariborz Jahanian QualType QT = Context.getBaseElementType(Iv->getType()); 348468dd3ee3b5ae5b7694b4a21e34b4355431ed0457Douglas Gregor if (QT->isRecordType()) 34852c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian Ivars.push_back(Iv); 3486786cd154f2a48d2b464679d33fcd5df0cd794c06Fariborz Jahanian } 3487786cd154f2a48d2b464679d33fcd5df0cd794c06Fariborz Jahanian} 3488e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian 34893fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanianvoid Sema::DiagnoseUseOfUnimplementedSelectors() { 34905b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor // Load referenced selectors from the external source. 34915b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor if (ExternalSource) { 34925b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor SmallVector<std::pair<Selector, SourceLocation>, 4> Sels; 34935b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor ExternalSource->ReadReferencedSelectors(Sels); 34945b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor for (unsigned I = 0, N = Sels.size(); I != N; ++I) 34955b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor ReferencedSelectors[Sels[I].first] = Sels[I].second; 34965b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor } 34975b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor 34988b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian // Warning will be issued only when selector table is 34998b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian // generated (which means there is at lease one implementation 35008b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian // in the TU). This is to match gcc's behavior. 35018b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian if (ReferencedSelectors.empty() || 35028b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian !Context.AnyObjCImplementation()) 35033fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian return; 35043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar for (auto &SelectorAndLocation : ReferencedSelectors) { 35053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Selector Sel = SelectorAndLocation.first; 35063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar SourceLocation Loc = SelectorAndLocation.second; 35073fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian if (!LookupImplementedMethodInGlobalPool(Sel)) 35083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Diag(Loc, diag::warn_unimplemented_selector) << Sel; 35093fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian } 35103fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian return; 35113fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian} 35124e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian 35134e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz JahanianObjCIvarDecl * 35144e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz JahanianSema::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, 35154e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian const ObjCPropertyDecl *&PDecl) const { 3516651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Method->isClassMethod()) 35176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 35184e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian const ObjCInterfaceDecl *IDecl = Method->getClassInterface(); 35194e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian if (!IDecl) 35206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 3521651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Method = IDecl->lookupMethod(Method->getSelector(), /*isInstance=*/true, 3522651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /*shallowCategoryLookup=*/false, 3523651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /*followSuper=*/false); 35244e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian if (!Method || !Method->isPropertyAccessor()) 35256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 3526651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if ((PDecl = Method->findPropertyDecl())) 3527651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl()) { 3528651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // property backing ivar must belong to property's class 3529651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // or be a private ivar in class's implementation. 3530651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // FIXME. fix the const-ness issue. 3531651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IV = const_cast<ObjCInterfaceDecl *>(IDecl)->lookupInstanceVariable( 3532651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IV->getIdentifier()); 3533651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return IV; 3534651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 35356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 35364e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian} 35374e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian 3538651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace { 3539651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Used by Sema::DiagnoseUnusedBackingIvarInAccessor to check if a property 3540651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// accessor references the backing ivar. 3541651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines class UnusedBackingIvarChecker : 3542651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines public DataRecursiveASTVisitor<UnusedBackingIvarChecker> { 3543651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines public: 3544651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Sema &S; 3545651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ObjCMethodDecl *Method; 3546651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ObjCIvarDecl *IvarD; 3547651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool AccessedIvar; 3548651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool InvokedSelfMethod; 3549651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3550651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines UnusedBackingIvarChecker(Sema &S, const ObjCMethodDecl *Method, 3551651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ObjCIvarDecl *IvarD) 3552651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : S(S), Method(Method), IvarD(IvarD), 3553651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AccessedIvar(false), InvokedSelfMethod(false) { 3554651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(IvarD); 3555651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 3556651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3557651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { 3558651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (E->getDecl() == IvarD) { 3559651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AccessedIvar = true; 3560651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 3561651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 3562651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 3563651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 3564651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool VisitObjCMessageExpr(ObjCMessageExpr *E) { 3566651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (E->getReceiverKind() == ObjCMessageExpr::Instance && 3567651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.isSelfExpr(E->getInstanceReceiver(), Method)) { 3568651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines InvokedSelfMethod = true; 3569651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 3570651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 3571651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 3572651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines }; 3573651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 3574651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3575651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Sema::DiagnoseUnusedBackingIvarInAccessor(Scope *S, 3576651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ObjCImplementationDecl *ImplD) { 3577651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (S->hasUnrecoverableErrorOccurred()) 35784e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian return; 3579651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3580651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *CurMethod : ImplD->instance_methods()) { 3581651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned DIAG = diag::warn_unused_property_backing_ivar; 3582651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation Loc = CurMethod->getLocation(); 3583c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Diags.isIgnored(DIAG, Loc)) 3584651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 3585651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3586651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ObjCPropertyDecl *PDecl; 3587651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ObjCIvarDecl *IV = GetIvarBackingPropertyAccessor(CurMethod, PDecl); 3588651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!IV) 3589651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 3590651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3591651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines UnusedBackingIvarChecker Checker(*this, CurMethod, IV); 3592651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Checker.TraverseStmt(CurMethod->getBody()); 3593651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Checker.AccessedIvar) 3594651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 3595651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3596651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Do not issue this warning if backing ivar is used somewhere and accessor 3597651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // implementation makes a self call. This is to prevent false positive in 3598651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // cases where the ivar is accessed by another method that the accessor 3599651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // delegates to. 3600651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!IV->isReferenced() || !Checker.InvokedSelfMethod) { 3601651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diag(Loc, DIAG) << IV; 3602651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diag(PDecl->getLocation(), diag::note_property_declare); 3603651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 36044e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian } 36054e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian} 3606