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" 1887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#include "clang/AST/RecursiveASTVisitor.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/Lookup.h" 2555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/Scope.h" 2655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/ScopeInfo.h" 2787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#include "llvm/ADT/DenseMap.h" 2850df6ae41f232612e5e88b19e0db9900d08d2f6cJohn McCall#include "llvm/ADT/DenseSet.h" 2987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#include "TypeLocBuilder.h" 3050df6ae41f232612e5e88b19e0db9900d08d2f6cJohn McCall 314d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattnerusing namespace clang; 324d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 33f85e193739c953358c865005855253af4f68a497John McCall/// Check whether the given method, which must be in the 'init' 34f85e193739c953358c865005855253af4f68a497John McCall/// family, is a valid member of that family. 35f85e193739c953358c865005855253af4f68a497John McCall/// 36f85e193739c953358c865005855253af4f68a497John McCall/// \param receiverTypeIfCall - if null, check this as if declaring it; 37f85e193739c953358c865005855253af4f68a497John McCall/// if non-null, check this as if making a call to it with the given 38f85e193739c953358c865005855253af4f68a497John McCall/// receiver type 39f85e193739c953358c865005855253af4f68a497John McCall/// 40f85e193739c953358c865005855253af4f68a497John McCall/// \return true to indicate that there was an error and appropriate 41f85e193739c953358c865005855253af4f68a497John McCall/// actions were taken 42f85e193739c953358c865005855253af4f68a497John McCallbool Sema::checkInitMethod(ObjCMethodDecl *method, 43f85e193739c953358c865005855253af4f68a497John McCall QualType receiverTypeIfCall) { 44f85e193739c953358c865005855253af4f68a497John McCall if (method->isInvalidDecl()) return true; 45f85e193739c953358c865005855253af4f68a497John McCall 46f85e193739c953358c865005855253af4f68a497John McCall // This castAs is safe: methods that don't return an object 47f85e193739c953358c865005855253af4f68a497John McCall // pointer won't be inferred as inits and will reject an explicit 48f85e193739c953358c865005855253af4f68a497John McCall // objc_method_family(init). 49f85e193739c953358c865005855253af4f68a497John McCall 50f85e193739c953358c865005855253af4f68a497John McCall // We ignore protocols here. Should we? What about Class? 51f85e193739c953358c865005855253af4f68a497John McCall 52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ObjCObjectType *result = 53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines method->getReturnType()->castAs<ObjCObjectPointerType>()->getObjectType(); 54f85e193739c953358c865005855253af4f68a497John McCall 55f85e193739c953358c865005855253af4f68a497John McCall if (result->isObjCId()) { 56f85e193739c953358c865005855253af4f68a497John McCall return false; 57f85e193739c953358c865005855253af4f68a497John McCall } else if (result->isObjCClass()) { 58f85e193739c953358c865005855253af4f68a497John McCall // fall through: always an error 59f85e193739c953358c865005855253af4f68a497John McCall } else { 60f85e193739c953358c865005855253af4f68a497John McCall ObjCInterfaceDecl *resultClass = result->getInterface(); 61f85e193739c953358c865005855253af4f68a497John McCall assert(resultClass && "unexpected object type!"); 62f85e193739c953358c865005855253af4f68a497John McCall 63f85e193739c953358c865005855253af4f68a497John McCall // It's okay for the result type to still be a forward declaration 64f85e193739c953358c865005855253af4f68a497John McCall // if we're checking an interface declaration. 657723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor if (!resultClass->hasDefinition()) { 66f85e193739c953358c865005855253af4f68a497John McCall if (receiverTypeIfCall.isNull() && 67f85e193739c953358c865005855253af4f68a497John McCall !isa<ObjCImplementationDecl>(method->getDeclContext())) 68f85e193739c953358c865005855253af4f68a497John McCall return false; 69f85e193739c953358c865005855253af4f68a497John McCall 70f85e193739c953358c865005855253af4f68a497John McCall // Otherwise, we try to compare class types. 71f85e193739c953358c865005855253af4f68a497John McCall } else { 72f85e193739c953358c865005855253af4f68a497John McCall // If this method was declared in a protocol, we can't check 73f85e193739c953358c865005855253af4f68a497John McCall // anything unless we have a receiver type that's an interface. 746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const ObjCInterfaceDecl *receiverClass = nullptr; 75f85e193739c953358c865005855253af4f68a497John McCall if (isa<ObjCProtocolDecl>(method->getDeclContext())) { 76f85e193739c953358c865005855253af4f68a497John McCall if (receiverTypeIfCall.isNull()) 77f85e193739c953358c865005855253af4f68a497John McCall return false; 78f85e193739c953358c865005855253af4f68a497John McCall 79f85e193739c953358c865005855253af4f68a497John McCall receiverClass = receiverTypeIfCall->castAs<ObjCObjectPointerType>() 80f85e193739c953358c865005855253af4f68a497John McCall ->getInterfaceDecl(); 81f85e193739c953358c865005855253af4f68a497John McCall 82f85e193739c953358c865005855253af4f68a497John McCall // This can be null for calls to e.g. id<Foo>. 83f85e193739c953358c865005855253af4f68a497John McCall if (!receiverClass) return false; 84f85e193739c953358c865005855253af4f68a497John McCall } else { 85f85e193739c953358c865005855253af4f68a497John McCall receiverClass = method->getClassInterface(); 86f85e193739c953358c865005855253af4f68a497John McCall assert(receiverClass && "method not associated with a class!"); 87f85e193739c953358c865005855253af4f68a497John McCall } 88f85e193739c953358c865005855253af4f68a497John McCall 89f85e193739c953358c865005855253af4f68a497John McCall // If either class is a subclass of the other, it's fine. 90f85e193739c953358c865005855253af4f68a497John McCall if (receiverClass->isSuperClassOf(resultClass) || 91f85e193739c953358c865005855253af4f68a497John McCall resultClass->isSuperClassOf(receiverClass)) 92f85e193739c953358c865005855253af4f68a497John McCall return false; 93f85e193739c953358c865005855253af4f68a497John McCall } 94f85e193739c953358c865005855253af4f68a497John McCall } 95f85e193739c953358c865005855253af4f68a497John McCall 96f85e193739c953358c865005855253af4f68a497John McCall SourceLocation loc = method->getLocation(); 97f85e193739c953358c865005855253af4f68a497John McCall 98f85e193739c953358c865005855253af4f68a497John McCall // If we're in a system header, and this is not a call, just make 99f85e193739c953358c865005855253af4f68a497John McCall // the method unusable. 100f85e193739c953358c865005855253af4f68a497John McCall if (receiverTypeIfCall.isNull() && getSourceManager().isInSystemHeader(loc)) { 10187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar method->addAttr(UnavailableAttr::CreateImplicit(Context, "", 10287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar UnavailableAttr::IR_ARCInitReturnsUnrelated, 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. 3224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar CheckParmsForFunctionDef(MDecl->parameters(), 3238c0501c7370d894a735692b92fab62bbb05d86bdReid Kleckner /*CheckParameterNames=*/false); 3248c0501c7370d894a735692b92fab62bbb05d86bdReid Kleckner 3258123a95c33b792d35c2e4992ba6e27882748fb0dChris Lattner // Introduce all of the other parameters into this scope. 3264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (auto *Param : MDecl->parameters()) { 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 44987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} // end anonymous namespace 4502f4d88f4418afafbd0b22ce0f79cdead6f3a6f99Kaelyn Uhrain 451b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainarstatic void diagnoseUseOfProtocols(Sema &TheSema, 452b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar ObjCContainerDecl *CD, 453b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar ObjCProtocolDecl *const *ProtoRefs, 454b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar unsigned NumProtoRefs, 455b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar const SourceLocation *ProtoLocs) { 456b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar assert(ProtoRefs); 457b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar // Diagnose availability in the context of the ObjC container. 458b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar Sema::ContextRAII SavedContext(TheSema, CD); 459b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar for (unsigned i = 0; i < NumProtoRefs; ++i) { 460b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar (void)TheSema.DiagnoseUseOfDecl(ProtoRefs[i], ProtoLocs[i]); 461b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar } 462b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar} 463b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar 46487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid Sema:: 46587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarActOnSuperClassOfClassInterface(Scope *S, 46687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation AtInterfaceLoc, 46787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCInterfaceDecl *IDecl, 46887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar IdentifierInfo *ClassName, 46987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation ClassLoc, 47087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar IdentifierInfo *SuperName, 47187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation SuperLoc, 47287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ArrayRef<ParsedType> SuperTypeArgs, 47387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceRange SuperTypeArgsRange) { 47487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Check if a different kind of symbol declared in this scope. 47587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar NamedDecl *PrevDecl = LookupSingleName(TUScope, SuperName, SuperLoc, 47687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar LookupOrdinaryName); 47787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 47887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!PrevDecl) { 47987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Try to correct for a typo in the superclass name without correcting 48087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // to the class we're defining. 48187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (TypoCorrection Corrected = CorrectTypo( 48287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar DeclarationNameInfo(SuperName, SuperLoc), 48387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar LookupOrdinaryName, TUScope, 48487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar nullptr, llvm::make_unique<ObjCInterfaceValidatorCCC>(IDecl), 48587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CTK_ErrorRecovery)) { 48687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest) 48787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << SuperName << ClassName); 48887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar PrevDecl = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>(); 48987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 49087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 49187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 49287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (declaresSameEntity(PrevDecl, IDecl)) { 49387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(SuperLoc, diag::err_recursive_superclass) 49487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc); 49587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar IDecl->setEndOfDefinitionLoc(ClassLoc); 49687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else { 49787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCInterfaceDecl *SuperClassDecl = 49887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl); 49987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar QualType SuperClassType; 50087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 50187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Diagnose classes that inherit from deprecated classes. 50287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (SuperClassDecl) { 50387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar (void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc); 50487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperClassType = Context.getObjCInterfaceType(SuperClassDecl); 50587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 50687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 50787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (PrevDecl && !SuperClassDecl) { 50887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // The previous declaration was not a class decl. Check if we have a 50987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // typedef. If we do, get the underlying class type. 51087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (const TypedefNameDecl *TDecl = 51187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) { 51287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar QualType T = TDecl->getUnderlyingType(); 51387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (T->isObjCObjectType()) { 51487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface()) { 51587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl); 51687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperClassType = Context.getTypeDeclType(TDecl); 51787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 51887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // This handles the following case: 51987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // @interface NewI @end 52087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // typedef NewI DeprI __attribute__((deprecated("blah"))) 52187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // @interface SI : DeprI /* warn here */ @end 52287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar (void)DiagnoseUseOfDecl(const_cast<TypedefNameDecl*>(TDecl), SuperLoc); 52387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 52487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 52587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 52687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 52787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // This handles the following case: 52887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // 52987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // typedef int SuperClass; 53087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // @interface MyClass : SuperClass {} @end 53187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // 53287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!SuperClassDecl) { 53387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName; 53487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(PrevDecl->getLocation(), diag::note_previous_definition); 53587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 53687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 53787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 53887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) { 53987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!SuperClassDecl) 54087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(SuperLoc, diag::err_undef_superclass) 54187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc); 54287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar else if (RequireCompleteType(SuperLoc, 54387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperClassType, 54487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diag::err_forward_superclass, 54587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperClassDecl->getDeclName(), 54687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ClassName, 54787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceRange(AtInterfaceLoc, ClassLoc))) { 54887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperClassDecl = nullptr; 54987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperClassType = QualType(); 55087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 55187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 55287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 55387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (SuperClassType.isNull()) { 55487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(!SuperClassDecl && "Failed to set SuperClassType?"); 55587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return; 55687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 55787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 55887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Handle type arguments on the superclass. 55987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar TypeSourceInfo *SuperClassTInfo = nullptr; 56087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!SuperTypeArgs.empty()) { 56187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar TypeResult fullSuperClassType = actOnObjCTypeArgsAndProtocolQualifiers( 56287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S, 56387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperLoc, 56487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CreateParsedType(SuperClassType, 56587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar nullptr), 56687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperTypeArgsRange.getBegin(), 56787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperTypeArgs, 56887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperTypeArgsRange.getEnd(), 56987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation(), 57087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar { }, 57187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar { }, 57287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation()); 57387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!fullSuperClassType.isUsable()) 57487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return; 57587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 57687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperClassType = GetTypeFromParser(fullSuperClassType.get(), 57787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar &SuperClassTInfo); 57887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 57987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 58087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!SuperClassTInfo) { 58187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperClassTInfo = Context.getTrivialTypeSourceInfo(SuperClassType, 58287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperLoc); 58387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 58487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 58587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar IDecl->setSuperClass(SuperClassTInfo); 58687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar IDecl->setEndOfDefinitionLoc(SuperClassTInfo->getTypeLoc().getLocEnd()); 58787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 58887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} 58987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 59087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarDeclResult Sema::actOnObjCTypeParam(Scope *S, 59187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCTypeParamVariance variance, 59287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation varianceLoc, 59387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar unsigned index, 59487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar IdentifierInfo *paramName, 59587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation paramLoc, 59687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation colonLoc, 59787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ParsedType parsedTypeBound) { 59887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If there was an explicitly-provided type bound, check it. 59987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar TypeSourceInfo *typeBoundInfo = nullptr; 60087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (parsedTypeBound) { 60187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // The type bound can be any Objective-C pointer type. 60287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar QualType typeBound = GetTypeFromParser(parsedTypeBound, &typeBoundInfo); 60387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (typeBound->isObjCObjectPointerType()) { 60487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // okay 60587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else if (typeBound->isObjCObjectType()) { 60687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // The user forgot the * on an Objective-C pointer type, e.g., 60787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // "T : NSView". 60887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation starLoc = getLocForEndOfToken( 60987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeBoundInfo->getTypeLoc().getEndLoc()); 61087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(typeBoundInfo->getTypeLoc().getBeginLoc(), 61187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diag::err_objc_type_param_bound_missing_pointer) 61287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << typeBound << paramName 61387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << FixItHint::CreateInsertion(starLoc, " *"); 61487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 61587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Create a new type location builder so we can update the type 61687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // location information we have. 61787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar TypeLocBuilder builder; 61887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar builder.pushFullCopy(typeBoundInfo->getTypeLoc()); 61987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 62087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Create the Objective-C pointer type. 62187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeBound = Context.getObjCObjectPointerType(typeBound); 62287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCObjectPointerTypeLoc newT 62387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar = builder.push<ObjCObjectPointerTypeLoc>(typeBound); 62487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar newT.setStarLoc(starLoc); 62587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 62687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Form the new type source information. 62787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeBoundInfo = builder.getTypeSourceInfo(Context, typeBound); 62887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else { 62987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Not a valid type bound. 63087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(typeBoundInfo->getTypeLoc().getBeginLoc(), 63187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diag::err_objc_type_param_bound_nonobject) 63287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << typeBound << paramName; 63387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 63487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Forget the bound; we'll default to id later. 63587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeBoundInfo = nullptr; 63687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 63787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 63887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Type bounds cannot have qualifiers (even indirectly) or explicit 63987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // nullability. 64087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (typeBoundInfo) { 64187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar QualType typeBound = typeBoundInfo->getType(); 64287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar TypeLoc qual = typeBoundInfo->getTypeLoc().findExplicitQualifierLoc(); 64387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (qual || typeBound.hasQualifiers()) { 64487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar bool diagnosed = false; 64587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceRange rangeToRemove; 64687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (qual) { 64787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto attr = qual.getAs<AttributedTypeLoc>()) { 64887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar rangeToRemove = attr.getLocalSourceRange(); 64987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (attr.getTypePtr()->getImmediateNullability()) { 65087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(attr.getLocStart(), 65187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diag::err_objc_type_param_bound_explicit_nullability) 65287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << paramName << typeBound 65387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << FixItHint::CreateRemoval(rangeToRemove); 65487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diagnosed = true; 65587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 65687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 65787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 65887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 65987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!diagnosed) { 66087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(qual ? qual.getLocStart() 66187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : typeBoundInfo->getTypeLoc().getLocStart(), 66287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diag::err_objc_type_param_bound_qualified) 66387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << paramName << typeBound << typeBound.getQualifiers().getAsString() 66487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << FixItHint::CreateRemoval(rangeToRemove); 66587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 66687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 66787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If the type bound has qualifiers other than CVR, we need to strip 66887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // them or we'll probably assert later when trying to apply new 66987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // qualifiers. 67087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Qualifiers quals = typeBound.getQualifiers(); 67187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar quals.removeCVRQualifiers(); 67287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!quals.empty()) { 67387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeBoundInfo = 67487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Context.getTrivialTypeSourceInfo(typeBound.getUnqualifiedType()); 67587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 67687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 67787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 67887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 67987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 68087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If there was no explicit type bound (or we removed it due to an error), 68187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // use 'id' instead. 68287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!typeBoundInfo) { 68387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar colonLoc = SourceLocation(); 68487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeBoundInfo = Context.getTrivialTypeSourceInfo(Context.getObjCIdType()); 68587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 68687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 68787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Create the type parameter. 68887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return ObjCTypeParamDecl::Create(Context, CurContext, variance, varianceLoc, 68987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar index, paramLoc, paramName, colonLoc, 69087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeBoundInfo); 69187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} 69287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 69387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarObjCTypeParamList *Sema::actOnObjCTypeParamList(Scope *S, 69487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation lAngleLoc, 69587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ArrayRef<Decl *> typeParamsIn, 69687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation rAngleLoc) { 69787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // We know that the array only contains Objective-C type parameters. 69887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ArrayRef<ObjCTypeParamDecl *> 69987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeParams( 70087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar reinterpret_cast<ObjCTypeParamDecl * const *>(typeParamsIn.data()), 70187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeParamsIn.size()); 70287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 70387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Diagnose redeclarations of type parameters. 70487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // We do this now because Objective-C type parameters aren't pushed into 70587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // scope until later (after the instance variable block), but we want the 70687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // diagnostics to occur right after we parse the type parameter list. 70787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::SmallDenseMap<IdentifierInfo *, ObjCTypeParamDecl *> knownParams; 70887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar for (auto typeParam : typeParams) { 70987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto known = knownParams.find(typeParam->getIdentifier()); 71087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (known != knownParams.end()) { 71187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(typeParam->getLocation(), diag::err_objc_type_param_redecl) 71287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << typeParam->getIdentifier() 71387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << SourceRange(known->second->getLocation()); 71487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 71587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeParam->setInvalidDecl(); 71687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else { 71787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar knownParams.insert(std::make_pair(typeParam->getIdentifier(), typeParam)); 71887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 71987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Push the type parameter into scope. 72087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar PushOnScopeChains(typeParam, S, /*AddToContext=*/false); 72187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 72287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 72387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 72487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Create the parameter list. 72587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return ObjCTypeParamList::create(Context, lAngleLoc, typeParams, rAngleLoc); 72687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} 72787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 72887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid Sema::popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList) { 72987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar for (auto typeParam : *typeParamList) { 73087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!typeParam->isInvalidDecl()) { 73187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S->RemoveDecl(typeParam); 73287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar IdResolver.RemoveDecl(typeParam); 73387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 73487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 73587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} 73687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 73787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarnamespace { 73887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /// The context in which an Objective-C type parameter list occurs, for use 73987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /// in diagnostics. 74087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar enum class TypeParamListContext { 74187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ForwardDeclaration, 74287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Definition, 74387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Category, 74487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Extension 74587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar }; 74687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} // end anonymous namespace 74787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 74887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// Check consistency between two Objective-C type parameter lists, e.g., 74987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// between a category/extension and an \@interface or between an \@class and an 75087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// \@interface. 75187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstatic bool checkTypeParamListConsistency(Sema &S, 75287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCTypeParamList *prevTypeParams, 75387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCTypeParamList *newTypeParams, 75487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar TypeParamListContext newContext) { 75587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If the sizes don't match, complain about that. 75687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (prevTypeParams->size() != newTypeParams->size()) { 75787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation diagLoc; 75887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (newTypeParams->size() > prevTypeParams->size()) { 75987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diagLoc = newTypeParams->begin()[prevTypeParams->size()]->getLocation(); 76087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else { 76187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diagLoc = S.getLocForEndOfToken(newTypeParams->back()->getLocEnd()); 76287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 76387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 76487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Diag(diagLoc, diag::err_objc_type_param_arity_mismatch) 76587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << static_cast<unsigned>(newContext) 76687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << (newTypeParams->size() > prevTypeParams->size()) 76787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << prevTypeParams->size() 76887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << newTypeParams->size(); 76987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 77087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return true; 77187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 77287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 77387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Match up the type parameters. 77487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar for (unsigned i = 0, n = prevTypeParams->size(); i != n; ++i) { 77587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCTypeParamDecl *prevTypeParam = prevTypeParams->begin()[i]; 77687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCTypeParamDecl *newTypeParam = newTypeParams->begin()[i]; 77787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 77887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Check for consistency of the variance. 77987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (newTypeParam->getVariance() != prevTypeParam->getVariance()) { 78087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (newTypeParam->getVariance() == ObjCTypeParamVariance::Invariant && 78187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar newContext != TypeParamListContext::Definition) { 78287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // When the new type parameter is invariant and is not part 78387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // of the definition, just propagate the variance. 78487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar newTypeParam->setVariance(prevTypeParam->getVariance()); 78587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else if (prevTypeParam->getVariance() 78687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar == ObjCTypeParamVariance::Invariant && 78787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar !(isa<ObjCInterfaceDecl>(prevTypeParam->getDeclContext()) && 78887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar cast<ObjCInterfaceDecl>(prevTypeParam->getDeclContext()) 78987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ->getDefinition() == prevTypeParam->getDeclContext())) { 79087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // When the old parameter is invariant and was not part of the 79187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // definition, just ignore the difference because it doesn't 79287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // matter. 79387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else { 79487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar { 79587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Diagnose the conflict and update the second declaration. 79687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation diagLoc = newTypeParam->getVarianceLoc(); 79787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (diagLoc.isInvalid()) 79887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diagLoc = newTypeParam->getLocStart(); 79987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 80087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto diag = S.Diag(diagLoc, 80187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diag::err_objc_type_param_variance_conflict) 80287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << static_cast<unsigned>(newTypeParam->getVariance()) 80387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << newTypeParam->getDeclName() 80487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << static_cast<unsigned>(prevTypeParam->getVariance()) 80587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << prevTypeParam->getDeclName(); 80687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar switch (prevTypeParam->getVariance()) { 80787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar case ObjCTypeParamVariance::Invariant: 80887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diag << FixItHint::CreateRemoval(newTypeParam->getVarianceLoc()); 80987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar break; 81087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 81187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar case ObjCTypeParamVariance::Covariant: 81287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar case ObjCTypeParamVariance::Contravariant: { 81387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar StringRef newVarianceStr 81487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar = prevTypeParam->getVariance() == ObjCTypeParamVariance::Covariant 81587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ? "__covariant" 81687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : "__contravariant"; 81787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (newTypeParam->getVariance() 81887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar == ObjCTypeParamVariance::Invariant) { 81987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diag << FixItHint::CreateInsertion(newTypeParam->getLocStart(), 82087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar (newVarianceStr + " ").str()); 82187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else { 82287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diag << FixItHint::CreateReplacement(newTypeParam->getVarianceLoc(), 82387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar newVarianceStr); 82487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 82587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 82687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 82787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 82887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 82987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Diag(prevTypeParam->getLocation(), diag::note_objc_type_param_here) 83087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << prevTypeParam->getDeclName(); 83187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 83287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Override the variance. 83387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar newTypeParam->setVariance(prevTypeParam->getVariance()); 83487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 83587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 83687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 83787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If the bound types match, there's nothing to do. 83887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (S.Context.hasSameType(prevTypeParam->getUnderlyingType(), 83987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar newTypeParam->getUnderlyingType())) 84087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar continue; 84187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 84287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If the new type parameter's bound was explicit, complain about it being 84387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // different from the original. 84487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (newTypeParam->hasExplicitBound()) { 84587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceRange newBoundRange = newTypeParam->getTypeSourceInfo() 84687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ->getTypeLoc().getSourceRange(); 84787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Diag(newBoundRange.getBegin(), diag::err_objc_type_param_bound_conflict) 84887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << newTypeParam->getUnderlyingType() 84987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << newTypeParam->getDeclName() 85087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << prevTypeParam->hasExplicitBound() 85187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << prevTypeParam->getUnderlyingType() 85287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << (newTypeParam->getDeclName() == prevTypeParam->getDeclName()) 85387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << prevTypeParam->getDeclName() 85487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << FixItHint::CreateReplacement( 85587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar newBoundRange, 85687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar prevTypeParam->getUnderlyingType().getAsString( 85787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Context.getPrintingPolicy())); 85887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 85987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Diag(prevTypeParam->getLocation(), diag::note_objc_type_param_here) 86087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << prevTypeParam->getDeclName(); 86187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 86287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Override the new type parameter's bound type with the previous type, 86387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // so that it's consistent. 86487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar newTypeParam->setTypeSourceInfo( 86587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Context.getTrivialTypeSourceInfo(prevTypeParam->getUnderlyingType())); 86687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar continue; 86787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 86887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 86987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // The new type parameter got the implicit bound of 'id'. That's okay for 87087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // categories and extensions (overwrite it later), but not for forward 87187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // declarations and @interfaces, because those must be standalone. 87287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (newContext == TypeParamListContext::ForwardDeclaration || 87387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar newContext == TypeParamListContext::Definition) { 87487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Diagnose this problem for forward declarations and definitions. 87587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation insertionLoc 87687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar = S.getLocForEndOfToken(newTypeParam->getLocation()); 87787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar std::string newCode 87887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar = " : " + prevTypeParam->getUnderlyingType().getAsString( 87987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Context.getPrintingPolicy()); 88087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Diag(newTypeParam->getLocation(), 88187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diag::err_objc_type_param_bound_missing) 88287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << prevTypeParam->getUnderlyingType() 88387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << newTypeParam->getDeclName() 88487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << (newContext == TypeParamListContext::ForwardDeclaration) 88587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << FixItHint::CreateInsertion(insertionLoc, newCode); 88687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 88787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Diag(prevTypeParam->getLocation(), diag::note_objc_type_param_here) 88887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << prevTypeParam->getDeclName(); 88987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 89087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 89187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Update the new type parameter's bound to match the previous one. 89287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar newTypeParam->setTypeSourceInfo( 89387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Context.getTrivialTypeSourceInfo(prevTypeParam->getUnderlyingType())); 89487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 89587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 89687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return false; 89787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} 89887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 899d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema:: 90087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarActOnStartClassInterface(Scope *S, SourceLocation AtInterfaceLoc, 9017caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner IdentifierInfo *ClassName, SourceLocation ClassLoc, 90287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCTypeParamList *typeParamList, 9037caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner IdentifierInfo *SuperName, SourceLocation SuperLoc, 90487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ArrayRef<ParsedType> SuperTypeArgs, 90587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceRange SuperTypeArgsRange, 906d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl * const *ProtoRefs, unsigned NumProtoRefs, 90718df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor const SourceLocation *ProtoLocs, 9087caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner SourceLocation EndProtoLoc, AttributeList *AttrList) { 9094d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner assert(ClassName && "Missing class identifier"); 9101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9114d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check for another declaration kind with the same name. 912c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, ClassLoc, 913c0b39640de335809ca7544f802751112619f30ccDouglas Gregor LookupOrdinaryName, ForRedeclaration); 91472c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor 915a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) { 9163c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName; 9175f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(PrevDecl->getLocation(), diag::note_previous_definition); 9184d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 9191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9207723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor // Create a declaration to describe this @interface. 9210af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl); 922e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis 923e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) { 924e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // A previous decl with a different name is because of 925e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // @compatibility_alias, for example: 926e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // \code 927e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // @class NewImage; 928e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // @compatibility_alias OldImage NewImage; 929e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // \endcode 930e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // A lookup for 'OldImage' will return the 'NewImage' decl. 931e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // 932e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // In such a case use the real declaration name, instead of the alias one, 933e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // otherwise we will break IdentifierResolver and redecls-chain invariants. 934e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // FIXME: If necessary, add a bit to indicate that this ObjCInterfaceDecl 935e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // has been aliased. 936e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis ClassName = PrevIDecl->getIdentifier(); 937e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis } 938e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis 93987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If there was a forward declaration with type parameters, check 94087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // for consistency. 94187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (PrevIDecl) { 94287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (ObjCTypeParamList *prevTypeParamList = PrevIDecl->getTypeParamList()) { 94387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (typeParamList) { 94487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Both have type parameter lists; check for consistency. 94587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (checkTypeParamListConsistency(*this, prevTypeParamList, 94687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeParamList, 94787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar TypeParamListContext::Definition)) { 94887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeParamList = nullptr; 94987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 95087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else { 95187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(ClassLoc, diag::err_objc_parameterized_forward_class_first) 95287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << ClassName; 95387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(prevTypeParamList->getLAngleLoc(), diag::note_previous_decl) 95487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << ClassName; 95587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 95687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Clone the type parameter list. 95787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SmallVector<ObjCTypeParamDecl *, 4> clonedTypeParams; 95887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar for (auto typeParam : *prevTypeParamList) { 95987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar clonedTypeParams.push_back( 96087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCTypeParamDecl::Create( 96187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Context, 96287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CurContext, 96387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeParam->getVariance(), 96487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation(), 96587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeParam->getIndex(), 96687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation(), 96787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeParam->getIdentifier(), 96887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation(), 96987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Context.getTrivialTypeSourceInfo(typeParam->getUnderlyingType()))); 97087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 97187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 97287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeParamList = ObjCTypeParamList::create(Context, 97387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation(), 97487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar clonedTypeParams, 97587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation()); 97687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 97787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 97887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 97987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 9807723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor ObjCInterfaceDecl *IDecl 9817723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName, 98287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeParamList, PrevIDecl, ClassLoc); 9837723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor if (PrevIDecl) { 9847723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor // Class already seen. Was it a definition? 9857723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) { 9867723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor Diag(AtInterfaceLoc, diag::err_duplicate_class_def) 9877723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor << PrevIDecl->getDeclName(); 9882e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor Diag(Def->getLocation(), diag::note_previous_definition); 9897723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor IDecl->setInvalidDecl(); 9904d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 991deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor } 9927723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor 9937723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor if (AttrList) 9947723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor ProcessDeclAttributeList(TUScope, IDecl, AttrList); 9957723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor PushOnScopeChains(IDecl, TUScope); 99674c730ad1f6818b676b0bad46d806a9176950328Sebastian Redl 9977723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor // Start the definition of this class. If we're in a redefinition case, there 9987723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor // may already be a definition, so we'll end up adding to it. 9992e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor if (!IDecl->hasDefinition()) 10002e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor IDecl->startDefinition(); 10012e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor 10024d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (SuperName) { 100387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Diagnose availability in the context of the @interface. 100487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ContextRAII SavedContext(*this, IDecl); 1005f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor 100687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ActOnSuperClassOfClassInterface(S, AtInterfaceLoc, IDecl, 100787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ClassName, ClassLoc, 100887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperName, SuperLoc, SuperTypeArgs, 100987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperTypeArgsRange); 10104d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } else { // we have a root class. 101105c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor IDecl->setEndOfDefinitionLoc(ClassLoc); 10124d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 10131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10140b17c61e8f143901ce11b4a6e5129ac63aaeee04Sebastian Redl // Check then save referenced protocols. 101506036d3709955a53297b4cbe14e20db88f321470Chris Lattner if (NumProtoRefs) { 1016b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar diagnoseUseOfProtocols(*this, IDecl, (ObjCProtocolDecl*const*)ProtoRefs, 1017b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar NumProtoRefs, ProtoLocs); 101831ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky IDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs, 101918df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor ProtoLocs, Context); 102005c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor IDecl->setEndOfDefinitionLoc(EndProtoLoc); 10214d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 10221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 102315281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson CheckObjCDeclScope(IDecl); 10243a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis return ActOnObjCContainerStartDefinition(IDecl); 10254d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 10264d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 1027a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian/// ActOnTypedefedProtocols - this action finds protocol list as part of the 1028a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian/// typedef'ed use for a qualified super class and adds them to the list 1029a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian/// of the protocols. 1030a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanianvoid Sema::ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs, 1031a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian IdentifierInfo *SuperName, 1032a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian SourceLocation SuperLoc) { 1033a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian if (!SuperName) 1034a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian return; 1035a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian NamedDecl* IDecl = LookupSingleName(TUScope, SuperName, SuperLoc, 1036a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian LookupOrdinaryName); 1037a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian if (!IDecl) 1038a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian return; 1039a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian 1040a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian if (const TypedefNameDecl *TDecl = dyn_cast_or_null<TypedefNameDecl>(IDecl)) { 1041a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian QualType T = TDecl->getUnderlyingType(); 1042a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian if (T->isObjCObjectType()) 1043a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian if (const ObjCObjectType *OPT = T->getAs<ObjCObjectType>()) 10440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ProtocolRefs.append(OPT->qual_begin(), OPT->qual_end()); 1045a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian } 1046a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian} 1047a924f847fcc3268ca2ce5c1bc5592a3774aeab80Fariborz Jahanian 1048de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith/// ActOnCompatibilityAlias - this action is called after complete parsing of 10491dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// a \@compatibility_alias declaration. It sets up the alias relationships. 1050de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard SmithDecl *Sema::ActOnCompatibilityAlias(SourceLocation AtLoc, 1051de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith IdentifierInfo *AliasName, 1052de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith SourceLocation AliasLocation, 1053de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith IdentifierInfo *ClassName, 1054de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith SourceLocation ClassLocation) { 10554d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Look for previous declaration of alias name 1056c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, AliasLocation, 1057c0b39640de335809ca7544f802751112619f30ccDouglas Gregor LookupOrdinaryName, ForRedeclaration); 10584d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (ADecl) { 1059104f96ba1a59026d6a71b4ef39ca127b56324e4aEli Friedman Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName; 10608b265bd5eba1394273693e6705a43adac6b6aa2fChris Lattner Diag(ADecl->getLocation(), diag::note_previous_declaration); 10616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 10624d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 10634d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check for class declaration 1064c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation, 1065c0b39640de335809ca7544f802751112619f30ccDouglas Gregor LookupOrdinaryName, ForRedeclaration); 1066162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (const TypedefNameDecl *TDecl = 1067162e1c1b487352434552147967c3dd296ebee2f7Richard Smith dyn_cast_or_null<TypedefNameDecl>(CDeclU)) { 1068305c658ebce84bb9833fc0e7675554656453b8e8Fariborz Jahanian QualType T = TDecl->getUnderlyingType(); 1069c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall if (T->isObjCObjectType()) { 1070c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface()) { 1071305c658ebce84bb9833fc0e7675554656453b8e8Fariborz Jahanian ClassName = IDecl->getIdentifier(); 1072c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation, 1073c0b39640de335809ca7544f802751112619f30ccDouglas Gregor LookupOrdinaryName, ForRedeclaration); 1074305c658ebce84bb9833fc0e7675554656453b8e8Fariborz Jahanian } 1075305c658ebce84bb9833fc0e7675554656453b8e8Fariborz Jahanian } 1076305c658ebce84bb9833fc0e7675554656453b8e8Fariborz Jahanian } 1077f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner ObjCInterfaceDecl *CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDeclU); 10786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!CDecl) { 10793c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(ClassLocation, diag::warn_undef_interface) << ClassName; 1080f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner if (CDeclU) 10818b265bd5eba1394273693e6705a43adac6b6aa2fChris Lattner Diag(CDeclU->getLocation(), diag::note_previous_declaration); 10826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 10834d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 10841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1085f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner // Everything checked out, instantiate a new alias declaration AST. 10861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCCompatibleAliasDecl *AliasDecl = 1087d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor ObjCCompatibleAliasDecl::Create(Context, CurContext, AtLoc, AliasName, CDecl); 10881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 108915281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson if (!CheckObjCDeclScope(AliasDecl)) 1090516ff43cc4e20b637335d3dfa5b197ca8faa09cbDouglas Gregor PushOnScopeChains(AliasDecl, TUScope); 1091d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor 1092d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return AliasDecl; 10934d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 10944d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 1095819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanianbool Sema::CheckForwardProtocolDeclarationForCircularDependency( 109661d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff IdentifierInfo *PName, 109761d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff SourceLocation &Ploc, SourceLocation PrevLoc, 1098819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian const ObjCList<ObjCProtocolDecl> &PList) { 1099819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian 1100819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian bool res = false; 110161d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff for (ObjCList<ObjCProtocolDecl>::iterator I = PList.begin(), 110261d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff E = PList.end(); I != E; ++I) { 1103c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor if (ObjCProtocolDecl *PDecl = LookupProtocol((*I)->getIdentifier(), 1104c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor Ploc)) { 110561d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff if (PDecl->getIdentifier() == PName) { 110661d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff Diag(Ploc, diag::err_protocol_has_circular_dependency); 110761d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff Diag(PrevLoc, diag::note_previous_definition); 1108819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian res = true; 110961d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff } 11105e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor 11115e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor if (!PDecl->hasDefinition()) 11125e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor continue; 11135e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor 1114819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian if (CheckForwardProtocolDeclarationForCircularDependency(PName, Ploc, 1115819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian PDecl->getLocation(), PDecl->getReferencedProtocols())) 1116819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian res = true; 111761d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff } 111861d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff } 1119819e9bfe398bd556f43ca1f0c24d1b3fa21f41efFariborz Jahanian return res; 112061d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff} 112161d6852f67b4416bb96f1613c1aa589c8cbc17dbSteve Naroff 1122d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl * 1123e13b9595dc1e2f4288bec34f3412359f648e84a5Chris LattnerSema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc, 1124e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner IdentifierInfo *ProtocolName, 1125e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner SourceLocation ProtocolLoc, 1126d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl * const *ProtoRefs, 1127e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner unsigned NumProtoRefs, 112818df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor const SourceLocation *ProtoLocs, 1129246e70f69cb8aeb67225c54690f1c6b25abd5a86Daniel Dunbar SourceLocation EndProtoLoc, 1130246e70f69cb8aeb67225c54690f1c6b25abd5a86Daniel Dunbar AttributeList *AttrList) { 113196b69a7305e20c98f1a3e2e7cd52e2d6c5d53835Fariborz Jahanian bool err = false; 1132246e70f69cb8aeb67225c54690f1c6b25abd5a86Daniel Dunbar // FIXME: Deal with AttrList. 11334d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner assert(ProtocolName && "Missing protocol identifier"); 113427c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor ObjCProtocolDecl *PrevDecl = LookupProtocol(ProtocolName, ProtocolLoc, 113527c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor ForRedeclaration); 11366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ObjCProtocolDecl *PDecl = nullptr; 11376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (ObjCProtocolDecl *Def = PrevDecl? PrevDecl->getDefinition() : nullptr) { 113827c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // If we already have a definition, complain. 113927c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName; 114027c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor Diag(Def->getLocation(), diag::note_previous_definition); 114127c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 114227c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // Create a new protocol that is completely distinct from previous 114327c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // declarations, and do not make this protocol available for name lookup. 114427c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // That way, we'll end up completely ignoring the duplicate. 114527c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // FIXME: Can we turn this into an error? 114627c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName, 114727c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor ProtocolLoc, AtProtoInterfaceLoc, 11486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /*PrevDecl=*/nullptr); 114927c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor PDecl->startDefinition(); 115027c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor } else { 115127c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor if (PrevDecl) { 115227c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // Check for circular dependencies among protocol declarations. This can 115327c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // only happen if this protocol was forward-declared. 11544fc04da71ed46d63dc991dbea4fd52341e56c0a1Argyrios Kyrtzidis ObjCList<ObjCProtocolDecl> PList; 11554fc04da71ed46d63dc991dbea4fd52341e56c0a1Argyrios Kyrtzidis PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context); 11564fc04da71ed46d63dc991dbea4fd52341e56c0a1Argyrios Kyrtzidis err = CheckForwardProtocolDeclarationForCircularDependency( 115727c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor ProtocolName, ProtocolLoc, PrevDecl->getLocation(), PList); 11584d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 115927c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 116027c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // Create the new declaration. 11611711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName, 1162b05d7b20171bbd2feb14b059f39332cbe1bf1014Argyrios Kyrtzidis ProtocolLoc, AtProtoInterfaceLoc, 1163c9d3c7edb513e9b8a6ab65b04133653e71d7a72bDouglas Gregor /*PrevDecl=*/PrevDecl); 116427c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 11656e378de1aebdfeb44f2a7677ed207b32b3a41fbfDouglas Gregor PushOnScopeChains(PDecl, TUScope); 11665e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor PDecl->startDefinition(); 1167cca59d77c4b84fd2da268018dbaf9431a621e75bChris Lattner } 11685e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor 1169bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian if (AttrList) 11709cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(TUScope, PDecl, AttrList); 117127c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 117227c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor // Merge attributes from previous declarations. 117327c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor if (PrevDecl) 117427c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor mergeDeclAttributes(PDecl, PrevDecl); 117527c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 117696b69a7305e20c98f1a3e2e7cd52e2d6c5d53835Fariborz Jahanian if (!err && NumProtoRefs ) { 1177c858105d41602a2dadb2efbc1af80a7b791ebac3Chris Lattner /// Check then save referenced protocols. 1178b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar diagnoseUseOfProtocols(*this, PDecl, (ObjCProtocolDecl*const*)ProtoRefs, 1179b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar NumProtoRefs, ProtoLocs); 118031ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky PDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs, 118118df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor ProtoLocs, Context); 11824d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 11831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump CheckObjCDeclScope(PDecl); 11853a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis return ActOnObjCContainerStartDefinition(PDecl); 11864d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 11874d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 1188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic bool NestedProtocolHasNoDefinition(ObjCProtocolDecl *PDecl, 1189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCProtocolDecl *&UndefinedProtocol) { 1190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!PDecl->hasDefinition() || PDecl->getDefinition()->isHidden()) { 1191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines UndefinedProtocol = PDecl; 1192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 1193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *PI : PDecl->protocols()) 1196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (NestedProtocolHasNoDefinition(PI, UndefinedProtocol)) { 1197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines UndefinedProtocol = PI; 1198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 1199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 1201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 1202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 12034d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// FindProtocolDeclaration - This routine looks up protocols and 12047ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar/// issues an error if they are not declared. It returns list of 12057ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar/// protocol declarations in its 'Protocols' argument. 12064d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattnervoid 1207b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga NainarSema::FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, 120887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ArrayRef<IdentifierLocPair> ProtocolId, 12095f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<Decl *> &Protocols) { 121087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar for (const IdentifierLocPair &Pair : ProtocolId) { 121187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCProtocolDecl *PDecl = LookupProtocol(Pair.first, Pair.second); 1212eacc39212e5960b2680067c006384c2e4804873aChris Lattner if (!PDecl) { 1213d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor TypoCorrection Corrected = CorrectTypo( 121487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar DeclarationNameInfo(Pair.first, Pair.second), 1215176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines LookupObjCProtocolName, TUScope, nullptr, 1216176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::make_unique<DeclFilterCCC<ObjCProtocolDecl>>(), 12176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CTK_ErrorRecovery); 12182d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith if ((PDecl = Corrected.getCorrectionDeclAs<ObjCProtocolDecl>())) 12192d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith diagnoseTypo(Corrected, PDiag(diag::err_undeclared_protocol_suggest) 122087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << Pair.first); 1221f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor } 1222f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor 1223f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor if (!PDecl) { 122487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(Pair.second, diag::err_undeclared_protocol) << Pair.first; 1225eacc39212e5960b2680067c006384c2e4804873aChris Lattner continue; 1226eacc39212e5960b2680067c006384c2e4804873aChris Lattner } 12273c9a0240b6db6ee02a24f48c753089bda48843aeFariborz Jahanian // If this is a forward protocol declaration, get its definition. 12283c9a0240b6db6ee02a24f48c753089bda48843aeFariborz Jahanian if (!PDecl->isThisDeclarationADefinition() && PDecl->getDefinition()) 12293c9a0240b6db6ee02a24f48c753089bda48843aeFariborz Jahanian PDecl = PDecl->getDefinition(); 1230b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar 1231b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar // For an objc container, delay protocol reference checking until after we 1232b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar // can set the objc decl as the availability context, otherwise check now. 1233b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar if (!ForObjCContainer) { 123487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar (void)DiagnoseUseOfDecl(PDecl, Pair.second); 1235b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar } 1236eacc39212e5960b2680067c006384c2e4804873aChris Lattner 1237eacc39212e5960b2680067c006384c2e4804873aChris Lattner // If this is a forward declaration and we are supposed to warn in this 1238eacc39212e5960b2680067c006384c2e4804873aChris Lattner // case, do it. 12390f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor // FIXME: Recover nicely in the hidden case. 1240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCProtocolDecl *UndefinedProtocol; 1241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 12420f9b9f37941ea709104f02d7dbe4ea18ab457605Douglas Gregor if (WarnOnDeclarations && 1243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NestedProtocolHasNoDefinition(PDecl, UndefinedProtocol)) { 124487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(Pair.second, diag::warn_undef_protocolref) << Pair.first; 1245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diag(UndefinedProtocol->getLocation(), diag::note_protocol_decl_undefined) 1246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << UndefinedProtocol; 1247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1248d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Protocols.push_back(PDecl); 12494d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 12504d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 12514d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 125287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarnamespace { 125387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// Callback to only accept typo corrections that are either 125487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// Objective-C protocols or valid Objective-C type arguments. 125587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarclass ObjCTypeArgOrProtocolValidatorCCC : public CorrectionCandidateCallback { 125687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ASTContext &Context; 125787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Sema::LookupNameKind LookupKind; 125887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar public: 125987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCTypeArgOrProtocolValidatorCCC(ASTContext &context, 126087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Sema::LookupNameKind lookupKind) 126187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : Context(context), LookupKind(lookupKind) { } 126287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 126387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar bool ValidateCandidate(const TypoCorrection &candidate) override { 126487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If we're allowed to find protocols and we have a protocol, accept it. 126587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (LookupKind != Sema::LookupOrdinaryName) { 126687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (candidate.getCorrectionDeclAs<ObjCProtocolDecl>()) 126787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return true; 126887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 126987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 127087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If we're allowed to find type names and we have one, accept it. 127187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (LookupKind != Sema::LookupObjCProtocolName) { 127287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If we have a type declaration, we might accept this result. 127387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto typeDecl = candidate.getCorrectionDeclAs<TypeDecl>()) { 127487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If we found a tag declaration outside of C++, skip it. This 127587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // can happy because we look for any name when there is no 127687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // bias to protocol or type names. 127787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (isa<RecordDecl>(typeDecl) && !Context.getLangOpts().CPlusPlus) 127887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return false; 127987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 128087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Make sure the type is something we would accept as a type 128187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // argument. 128287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto type = Context.getTypeDeclType(typeDecl); 128387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (type->isObjCObjectPointerType() || 128487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar type->isBlockPointerType() || 128587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar type->isDependentType() || 128687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar type->isObjCObjectType()) 128787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return true; 128887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 128987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return false; 129087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 129187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 129287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If we have an Objective-C class type, accept it; there will 129387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // be another fix to add the '*'. 129487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (candidate.getCorrectionDeclAs<ObjCInterfaceDecl>()) 129587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return true; 129687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 129787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return false; 129887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 129987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 130087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return false; 130187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 130287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}; 130387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} // end anonymous namespace 130487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 13054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid Sema::DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId, 13064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar SourceLocation ProtocolLoc, 13074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar IdentifierInfo *TypeArgId, 13084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar SourceLocation TypeArgLoc, 13094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar bool SelectProtocolFirst) { 13104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Diag(TypeArgLoc, diag::err_objc_type_args_and_protocols) 13114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar << SelectProtocolFirst << TypeArgId << ProtocolId 13124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar << SourceRange(ProtocolLoc); 13134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 13144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 131587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarvoid Sema::actOnObjCTypeArgsOrProtocolQualifiers( 131687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Scope *S, 131787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ParsedType baseType, 131887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation lAngleLoc, 131987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ArrayRef<IdentifierInfo *> identifiers, 132087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ArrayRef<SourceLocation> identifierLocs, 132187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation rAngleLoc, 132287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation &typeArgsLAngleLoc, 132387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SmallVectorImpl<ParsedType> &typeArgs, 132487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation &typeArgsRAngleLoc, 132587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation &protocolLAngleLoc, 132687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SmallVectorImpl<Decl *> &protocols, 132787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation &protocolRAngleLoc, 132887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar bool warnOnIncompleteProtocols) { 132987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Local function that updates the declaration specifiers with 133087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // protocol information. 133187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar unsigned numProtocolsResolved = 0; 133287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto resolvedAsProtocols = [&] { 133387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(numProtocolsResolved == identifiers.size() && "Unresolved protocols"); 133487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 133587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Determine whether the base type is a parameterized class, in 133687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // which case we want to warn about typos such as 133787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // "NSArray<NSObject>" (that should be NSArray<NSObject *>). 133887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCInterfaceDecl *baseClass = nullptr; 133987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar QualType base = GetTypeFromParser(baseType, nullptr); 134087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar bool allAreTypeNames = false; 134187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation firstClassNameLoc; 134287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!base.isNull()) { 134387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (const auto *objcObjectType = base->getAs<ObjCObjectType>()) { 134487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar baseClass = objcObjectType->getInterface(); 134587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (baseClass) { 134687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto typeParams = baseClass->getTypeParamList()) { 134787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (typeParams->size() == numProtocolsResolved) { 134887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Note that we should be looking for type names, too. 134987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar allAreTypeNames = true; 135087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 135187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 135287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 135387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 135487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 135587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 135687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar for (unsigned i = 0, n = protocols.size(); i != n; ++i) { 135787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCProtocolDecl *&proto 135887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar = reinterpret_cast<ObjCProtocolDecl *&>(protocols[i]); 135987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // For an objc container, delay protocol reference checking until after we 136087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // can set the objc decl as the availability context, otherwise check now. 136187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!warnOnIncompleteProtocols) { 136287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar (void)DiagnoseUseOfDecl(proto, identifierLocs[i]); 136387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 136487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 136587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If this is a forward protocol declaration, get its definition. 136687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!proto->isThisDeclarationADefinition() && proto->getDefinition()) 136787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar proto = proto->getDefinition(); 136887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 136987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If this is a forward declaration and we are supposed to warn in this 137087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // case, do it. 137187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FIXME: Recover nicely in the hidden case. 137287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCProtocolDecl *forwardDecl = nullptr; 137387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (warnOnIncompleteProtocols && 137487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar NestedProtocolHasNoDefinition(proto, forwardDecl)) { 137587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(identifierLocs[i], diag::warn_undef_protocolref) 137687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << proto->getDeclName(); 137787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(forwardDecl->getLocation(), diag::note_protocol_decl_undefined) 137887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << forwardDecl; 137987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 138087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 138187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If everything this far has been a type name (and we care 138287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // about such things), check whether this name refers to a type 138387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // as well. 138487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (allAreTypeNames) { 138587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto *decl = LookupSingleName(S, identifiers[i], identifierLocs[i], 138687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar LookupOrdinaryName)) { 138787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (isa<ObjCInterfaceDecl>(decl)) { 138887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (firstClassNameLoc.isInvalid()) 138987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar firstClassNameLoc = identifierLocs[i]; 139087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else if (!isa<TypeDecl>(decl)) { 139187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Not a type. 139287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar allAreTypeNames = false; 139387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 139487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else { 139587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar allAreTypeNames = false; 139687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 139787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 139887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 139987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 140087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // All of the protocols listed also have type names, and at least 140187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // one is an Objective-C class name. Check whether all of the 140287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // protocol conformances are declared by the base class itself, in 140387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // which case we warn. 140487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (allAreTypeNames && firstClassNameLoc.isValid()) { 140587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::SmallPtrSet<ObjCProtocolDecl*, 8> knownProtocols; 140687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Context.CollectInheritedProtocols(baseClass, knownProtocols); 140787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar bool allProtocolsDeclared = true; 140887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar for (auto proto : protocols) { 140987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (knownProtocols.count(static_cast<ObjCProtocolDecl *>(proto)) == 0) { 141087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar allProtocolsDeclared = false; 141187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar break; 141287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 141387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 141487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 141587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (allProtocolsDeclared) { 141687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(firstClassNameLoc, diag::warn_objc_redundant_qualified_class_type) 141787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << baseClass->getDeclName() << SourceRange(lAngleLoc, rAngleLoc) 141887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << FixItHint::CreateInsertion(getLocForEndOfToken(firstClassNameLoc), 141987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar " *"); 142087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 142187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 142287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 142387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar protocolLAngleLoc = lAngleLoc; 142487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar protocolRAngleLoc = rAngleLoc; 142587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(protocols.size() == identifierLocs.size()); 142687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar }; 142787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 142887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Attempt to resolve all of the identifiers as protocols. 142987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar for (unsigned i = 0, n = identifiers.size(); i != n; ++i) { 143087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCProtocolDecl *proto = LookupProtocol(identifiers[i], identifierLocs[i]); 143187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar protocols.push_back(proto); 143287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (proto) 143387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ++numProtocolsResolved; 143487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 143587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 143687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If all of the names were protocols, these were protocol qualifiers. 143787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (numProtocolsResolved == identifiers.size()) 143887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return resolvedAsProtocols(); 143987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 144087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Attempt to resolve all of the identifiers as type names or 144187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Objective-C class names. The latter is technically ill-formed, 144287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // but is probably something like \c NSArray<NSView *> missing the 144387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // \c*. 144487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typedef llvm::PointerUnion<TypeDecl *, ObjCInterfaceDecl *> TypeOrClassDecl; 144587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SmallVector<TypeOrClassDecl, 4> typeDecls; 144687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar unsigned numTypeDeclsResolved = 0; 144787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar for (unsigned i = 0, n = identifiers.size(); i != n; ++i) { 144887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar NamedDecl *decl = LookupSingleName(S, identifiers[i], identifierLocs[i], 144987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar LookupOrdinaryName); 145087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!decl) { 145187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeDecls.push_back(TypeOrClassDecl()); 145287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar continue; 145387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 145487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 145587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto typeDecl = dyn_cast<TypeDecl>(decl)) { 145687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeDecls.push_back(typeDecl); 145787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ++numTypeDeclsResolved; 145887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar continue; 145987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 146087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 146187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto objcClass = dyn_cast<ObjCInterfaceDecl>(decl)) { 146287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeDecls.push_back(objcClass); 146387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ++numTypeDeclsResolved; 146487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar continue; 146587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 146687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 146787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeDecls.push_back(TypeOrClassDecl()); 146887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 146987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 147087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar AttributeFactory attrFactory; 147187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 147287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Local function that forms a reference to the given type or 147387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Objective-C class declaration. 147487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto resolveTypeReference = [&](TypeOrClassDecl typeDecl, SourceLocation loc) 147587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar -> TypeResult { 147687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Form declaration specifiers. They simply refer to the type. 147787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar DeclSpec DS(attrFactory); 147887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar const char* prevSpec; // unused 147987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar unsigned diagID; // unused 148087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar QualType type; 148187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto *actualTypeDecl = typeDecl.dyn_cast<TypeDecl *>()) 148287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar type = Context.getTypeDeclType(actualTypeDecl); 148387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar else 148487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar type = Context.getObjCInterfaceType(typeDecl.get<ObjCInterfaceDecl *>()); 148587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar TypeSourceInfo *parsedTSInfo = Context.getTrivialTypeSourceInfo(type, loc); 148687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ParsedType parsedType = CreateParsedType(type, parsedTSInfo); 148787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar DS.SetTypeSpecType(DeclSpec::TST_typename, loc, prevSpec, diagID, 148887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar parsedType, Context.getPrintingPolicy()); 148987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Use the identifier location for the type source range. 149087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar DS.SetRangeStart(loc); 149187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar DS.SetRangeEnd(loc); 149287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 149387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Form the declarator. 149487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Declarator D(DS, Declarator::TypeNameContext); 149587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 149687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If we have a typedef of an Objective-C class type that is missing a '*', 149787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // add the '*'. 149887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (type->getAs<ObjCInterfaceType>()) { 149987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation starLoc = getLocForEndOfToken(loc); 150087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ParsedAttributes parsedAttrs(attrFactory); 150187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar D.AddTypeInfo(DeclaratorChunk::getPointer(/*typeQuals=*/0, starLoc, 150287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation(), 150387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation(), 150487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation(), 15054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar SourceLocation(), 150687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation()), 150787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar parsedAttrs, 150887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar starLoc); 150987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 151087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Diagnose the missing '*'. 151187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(loc, diag::err_objc_type_arg_missing_star) 151287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << type 151387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << FixItHint::CreateInsertion(starLoc, " *"); 151487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 151587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 151687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Convert this to a type. 151787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return ActOnTypeName(S, D); 151887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar }; 151987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 152087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Local function that updates the declaration specifiers with 152187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // type argument information. 152287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto resolvedAsTypeDecls = [&] { 152387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // We did not resolve these as protocols. 152487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar protocols.clear(); 152587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 152687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(numTypeDeclsResolved == identifiers.size() && "Unresolved type decl"); 152787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Map type declarations to type arguments. 152887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar for (unsigned i = 0, n = identifiers.size(); i != n; ++i) { 152987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Map type reference to a type. 153087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar TypeResult type = resolveTypeReference(typeDecls[i], identifierLocs[i]); 153187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!type.isUsable()) { 153287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeArgs.clear(); 153387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return; 153487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 153587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 153687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeArgs.push_back(type.get()); 153787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 153887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 153987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeArgsLAngleLoc = lAngleLoc; 154087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeArgsRAngleLoc = rAngleLoc; 154187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar }; 154287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 154387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If all of the identifiers can be resolved as type names or 154487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Objective-C class names, we have type arguments. 154587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (numTypeDeclsResolved == identifiers.size()) 154687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return resolvedAsTypeDecls(); 154787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 154887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Error recovery: some names weren't found, or we have a mix of 154987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // type and protocol names. Go resolve all of the unresolved names 155087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // and complain if we can't find a consistent answer. 155187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar LookupNameKind lookupKind = LookupAnyName; 155287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar for (unsigned i = 0, n = identifiers.size(); i != n; ++i) { 155387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If we already have a protocol or type. Check whether it is the 155487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // right thing. 155587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (protocols[i] || typeDecls[i]) { 155687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If we haven't figured out whether we want types or protocols 155787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // yet, try to figure it out from this name. 155887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (lookupKind == LookupAnyName) { 155987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If this name refers to both a protocol and a type (e.g., \c 156087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // NSObject), don't conclude anything yet. 156187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (protocols[i] && typeDecls[i]) 156287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar continue; 156387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 156487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Otherwise, let this name decide whether we'll be correcting 156587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // toward types or protocols. 156687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar lookupKind = protocols[i] ? LookupObjCProtocolName 156787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : LookupOrdinaryName; 156887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar continue; 156987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 157087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 157187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If we want protocols and we have a protocol, there's nothing 157287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // more to do. 157387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (lookupKind == LookupObjCProtocolName && protocols[i]) 157487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar continue; 157587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 157687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If we want types and we have a type declaration, there's 157787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // nothing more to do. 157887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (lookupKind == LookupOrdinaryName && typeDecls[i]) 157987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar continue; 158087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 158187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // We have a conflict: some names refer to protocols and others 158287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // refer to types. 15834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar DiagnoseTypeArgsAndProtocols(identifiers[0], identifierLocs[0], 15844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar identifiers[i], identifierLocs[i], 15854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar protocols[i] != nullptr); 158687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 158787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar protocols.clear(); 158887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeArgs.clear(); 158987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return; 159087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 159187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 159287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Perform typo correction on the name. 159387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar TypoCorrection corrected = CorrectTypo( 159487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar DeclarationNameInfo(identifiers[i], identifierLocs[i]), lookupKind, S, 159587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar nullptr, 159687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm::make_unique<ObjCTypeArgOrProtocolValidatorCCC>(Context, 159787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar lookupKind), 159887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CTK_ErrorRecovery); 159987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (corrected) { 160087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Did we find a protocol? 160187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto proto = corrected.getCorrectionDeclAs<ObjCProtocolDecl>()) { 160287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diagnoseTypo(corrected, 160387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar PDiag(diag::err_undeclared_protocol_suggest) 160487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << identifiers[i]); 160587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar lookupKind = LookupObjCProtocolName; 160687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar protocols[i] = proto; 160787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ++numProtocolsResolved; 160887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar continue; 160987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 161087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 161187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Did we find a type? 161287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto typeDecl = corrected.getCorrectionDeclAs<TypeDecl>()) { 161387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diagnoseTypo(corrected, 161487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar PDiag(diag::err_unknown_typename_suggest) 161587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << identifiers[i]); 161687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar lookupKind = LookupOrdinaryName; 161787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeDecls[i] = typeDecl; 161887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ++numTypeDeclsResolved; 161987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar continue; 162087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 162187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 162287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Did we find an Objective-C class? 162387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto objcClass = corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) { 162487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diagnoseTypo(corrected, 162587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar PDiag(diag::err_unknown_type_or_class_name_suggest) 162687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << identifiers[i] << true); 162787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar lookupKind = LookupOrdinaryName; 162887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeDecls[i] = objcClass; 162987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ++numTypeDeclsResolved; 163087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar continue; 163187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 163287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 163387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 163487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // We couldn't find anything. 163587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(identifierLocs[i], 163687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar (lookupKind == LookupAnyName ? diag::err_objc_type_arg_missing 163787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : lookupKind == LookupObjCProtocolName ? diag::err_undeclared_protocol 163887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : diag::err_unknown_typename)) 163987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << identifiers[i]; 164087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar protocols.clear(); 164187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeArgs.clear(); 164287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return; 164387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 164487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 164587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If all of the names were (corrected to) protocols, these were 164687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // protocol qualifiers. 164787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (numProtocolsResolved == identifiers.size()) 164887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return resolvedAsProtocols(); 164987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 165087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Otherwise, all of the names were (corrected to) types. 165187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(numTypeDeclsResolved == identifiers.size() && "Not all types?"); 165287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return resolvedAsTypeDecls(); 165387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} 165487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 165578c39c76103a36e37a05b1e40da93850ea64647bFariborz Jahanian/// DiagnoseClassExtensionDupMethods - Check for duplicate declaration of 1656b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian/// a class method in its extension. 1657b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian/// 16581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, 1659b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian ObjCInterfaceDecl *ID) { 1660b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian if (!ID) 1661b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian return; // Possibly due to previous error 1662b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian 1663b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian llvm::DenseMap<Selector, const ObjCMethodDecl*> MethodMap; 1664651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *MD : ID->methods()) 1665b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian MethodMap[MD->getSelector()] = MD; 1666b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian 1667b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian if (MethodMap.empty()) 1668b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian return; 1669651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *Method : CAT->methods()) { 1670b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian const ObjCMethodDecl *&PrevMethod = MethodMap[Method->getSelector()]; 1671651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (PrevMethod && 1672651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (PrevMethod->isInstanceMethod() == Method->isInstanceMethod()) && 1673651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines !MatchTwoMethodDeclarations(Method, PrevMethod)) { 1674b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian Diag(Method->getLocation(), diag::err_duplicate_method_decl) 1675b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian << Method->getDeclName(); 1676b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian Diag(PrevMethod->getLocation(), diag::note_previous_declaration); 1677b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian } 1678b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian } 1679b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian} 1680b7f95f5b29ea4ba4231cbcbe581502ece5033795Fariborz Jahanian 16811dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// ActOnForwardProtocolDeclaration - Handle \@protocol foo; 1682bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas GregorSema::DeclGroupPtrTy 16834d3914836e85258e9ace7306999413e3c7ea6c11Chris LattnerSema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc, 168487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ArrayRef<IdentifierLocPair> IdentList, 1685bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian AttributeList *attrList) { 1686bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor SmallVector<Decl *, 8> DeclsInGroup; 168787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar for (const IdentifierLocPair &IdentPair : IdentList) { 168887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar IdentifierInfo *Ident = IdentPair.first; 168987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCProtocolDecl *PrevDecl = LookupProtocol(Ident, IdentPair.second, 169027c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor ForRedeclaration); 169127c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor ObjCProtocolDecl *PDecl 169227c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor = ObjCProtocolDecl::Create(Context, CurContext, Ident, 169387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar IdentPair.second, AtProtocolLoc, 1694c9d3c7edb513e9b8a6ab65b04133653e71d7a72bDouglas Gregor PrevDecl); 169527c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 169627c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor PushOnScopeChains(PDecl, TUScope); 1697bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor CheckObjCDeclScope(PDecl); 169827c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 16993937f87e53b3ee0c8da93536f48f6f96c006309dDouglas Gregor if (attrList) 17009cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(TUScope, PDecl, attrList); 170127c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 170227c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor if (PrevDecl) 170327c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor mergeDeclAttributes(PDecl, PrevDecl); 170427c6da284f90e32cda0ec8f52a2b6ba5a2613252Douglas Gregor 1705bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor DeclsInGroup.push_back(PDecl); 17064d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 17071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17084549d7ffc15bdd7ab860aa68db089d9f559b79e7Rafael Espindola return BuildDeclaratorGroup(DeclsInGroup, false); 17094d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 17104d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 1711d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema:: 17127caeabd868d46cf4e68478c6e9136dae4e735d21Chris LattnerActOnStartCategoryInterface(SourceLocation AtInterfaceLoc, 17137caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner IdentifierInfo *ClassName, SourceLocation ClassLoc, 171487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCTypeParamList *typeParamList, 17157caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner IdentifierInfo *CategoryName, 17167caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner SourceLocation CategoryLoc, 1717d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl * const *ProtoRefs, 17187caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner unsigned NumProtoRefs, 171918df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor const SourceLocation *ProtoLocs, 17207caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner SourceLocation EndProtoLoc) { 172180aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian ObjCCategoryDecl *CDecl; 1722c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true); 172309b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek 172409b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek /// Check that class of this category is already completely declared. 1725b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor 1726b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor if (!IDecl 1727b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor || RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), 1728d10099e5c8238fa0327f03921cf2e3c8975c881eDouglas Gregor diag::err_category_forward_interface, 17296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CategoryName == nullptr)) { 173009b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek // Create an invalid ObjCCategoryDecl to serve as context for 173109b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek // the enclosing method declarations. We mark the decl invalid 173209b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek // to make it clear that this isn't a valid AST. 173309b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, 173487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ClassLoc, CategoryLoc, CategoryName, 173587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar IDecl, typeParamList); 173609b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek CDecl->setInvalidDecl(); 17379a0b6b4e2bf6a9ef41d32b4e83f2911981d2d44dArgyrios Kyrtzidis CurContext->addDecl(CDecl); 1738b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor 1739b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor if (!IDecl) 1740b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor Diag(ClassLoc, diag::err_undef_interface) << ClassName; 17413a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis return ActOnObjCContainerStartDefinition(CDecl); 174209b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek } 174309b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek 174480aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian if (!CategoryName && IDecl->getImplementation()) { 174580aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian Diag(ClassLoc, diag::err_class_extension_after_impl) << ClassName; 174680aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian Diag(IDecl->getImplementation()->getLocation(), 174780aa1cd7973561889e51c1c152c8990a8de9c953Fariborz Jahanian diag::note_implementation_declared); 174809b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek } 174909b6897d967c50db36ad83b910060ea7d68a21bcTed Kremenek 175025760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian if (CategoryName) { 175125760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian /// Check for duplicate interface declaration for this category 1752d329724745b49f894b768d47275b7c2713106e89Douglas Gregor if (ObjCCategoryDecl *Previous 1753d329724745b49f894b768d47275b7c2713106e89Douglas Gregor = IDecl->FindCategoryDeclaration(CategoryName)) { 1754d329724745b49f894b768d47275b7c2713106e89Douglas Gregor // Class extensions can be declared multiple times, categories cannot. 1755d329724745b49f894b768d47275b7c2713106e89Douglas Gregor Diag(CategoryLoc, diag::warn_dup_category_def) 1756d329724745b49f894b768d47275b7c2713106e89Douglas Gregor << ClassName << CategoryName; 1757d329724745b49f894b768d47275b7c2713106e89Douglas Gregor Diag(Previous->getLocation(), diag::note_previous_definition); 17584d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 17597c453b3ded5dc9bff05e6e66eb725a0938303d73Fariborz Jahanian } 17604d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 176187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If we have a type parameter list, check it. 176287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (typeParamList) { 176387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto prevTypeParamList = IDecl->getTypeParamList()) { 176487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (checkTypeParamListConsistency(*this, prevTypeParamList, typeParamList, 176587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CategoryName 176687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ? TypeParamListContext::Category 176787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : TypeParamListContext::Extension)) 176887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeParamList = nullptr; 176987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else { 177087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(typeParamList->getLAngleLoc(), 177187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diag::err_objc_parameterized_category_nonclass) 177287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << (CategoryName != nullptr) 177387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << ClassName 177487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << typeParamList->getSourceRange(); 177587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 177687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeParamList = nullptr; 177787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 177887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 177987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 1780955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, 178187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ClassLoc, CategoryLoc, CategoryName, IDecl, 178287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typeParamList); 1783955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis // FIXME: PushOnScopeChains? 1784955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis CurContext->addDecl(CDecl); 1785955fadbdfecfa24a590febe66a86519096787f2dArgyrios Kyrtzidis 17864d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (NumProtoRefs) { 1787b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar diagnoseUseOfProtocols(*this, CDecl, (ObjCProtocolDecl*const*)ProtoRefs, 1788b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar NumProtoRefs, ProtoLocs); 1789b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar CDecl->setProtocolList((ObjCProtocolDecl*const*)ProtoRefs, NumProtoRefs, 179018df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor ProtoLocs, Context); 1791339798eae1eb61c50ca68766ed028c0a16d0a284Fariborz Jahanian // Protocols in the class extension belong to the class. 179225760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian if (CDecl->IsClassExtension()) 179331ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky IDecl->mergeClassExtensionProtocolList((ObjCProtocolDecl*const*)ProtoRefs, 179453b9441b5a81a24fa1f66f3f6416f1e36baa9c2fTed Kremenek NumProtoRefs, Context); 17954d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 17961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 179715281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson CheckObjCDeclScope(CDecl); 17983a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis return ActOnObjCContainerStartDefinition(CDecl); 17994d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 18004d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 18014d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// ActOnStartCategoryImplementation - Perform semantic checks on the 1802a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// category implementation declaration and build an ObjCCategoryImplDecl 18034d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// object. 1804d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema::ActOnStartCategoryImplementation( 18054d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner SourceLocation AtCatImplLoc, 18064d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner IdentifierInfo *ClassName, SourceLocation ClassLoc, 18074d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner IdentifierInfo *CatName, SourceLocation CatLoc) { 1808c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true); 18096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ObjCCategoryDecl *CatIDecl = nullptr; 18105a61e0c4229dc82617a37a68ac2fc08d46e00488Argyrios Kyrtzidis if (IDecl && IDecl->hasDefinition()) { 18118a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis CatIDecl = IDecl->FindCategoryDeclaration(CatName); 18128a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis if (!CatIDecl) { 18138a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis // Category @implementation with no corresponding @interface. 18148a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis // Create and install one. 181537f40572c4c78a8c57a7b45266f8b86db172a7c1Argyrios Kyrtzidis CatIDecl = ObjCCategoryDecl::Create(Context, CurContext, AtCatImplLoc, 181637f40572c4c78a8c57a7b45266f8b86db172a7c1Argyrios Kyrtzidis ClassLoc, CatLoc, 181787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CatName, IDecl, 181887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /*typeParamList=*/nullptr); 181937f40572c4c78a8c57a7b45266f8b86db172a7c1Argyrios Kyrtzidis CatIDecl->setImplicit(); 18208a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis } 18218a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis } 18228a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis 18231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCCategoryImplDecl *CDecl = 18241711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis ObjCCategoryImplDecl::Create(Context, CurContext, CatName, IDecl, 1825c6994005dc9f677c831b8e90bdab483cc2197c29Argyrios Kyrtzidis ClassLoc, AtCatImplLoc, CatLoc); 18264d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner /// Check that class of this category is already completely declared. 1827b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor if (!IDecl) { 18283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(ClassLoc, diag::err_undef_interface) << ClassName; 18296c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall CDecl->setInvalidDecl(); 1830b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor } else if (RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), 1831b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor diag::err_undef_interface)) { 1832b3029960632ca8a3248e74770eda64d6c16f7246Douglas Gregor CDecl->setInvalidDecl(); 18336c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 18344d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 1835d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor // FIXME: PushOnScopeChains? 183617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis CurContext->addDecl(CDecl); 1837d04341000d35c8808a72838b057eed7bf13b7661Douglas Gregor 1838c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis // If the interface is deprecated/unavailable, warn/error about it. 1839c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis if (IDecl) 1840c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis DiagnoseUseOfDecl(IDecl, ClassLoc); 1841c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis 18424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // If the interface has the objc_runtime_visible attribute, we 18434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // cannot implement a category for it. 18444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (IDecl && IDecl->hasAttr<ObjCRuntimeVisibleAttr>()) { 18454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Diag(ClassLoc, diag::err_objc_runtime_visible_category) 18464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar << IDecl->getDeclName(); 18474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 18484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 18498a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis /// Check that CatName, category name, is not used in another implementation. 18508a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis if (CatIDecl) { 18518a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis if (CatIDecl->getImplementation()) { 18528a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis Diag(ClassLoc, diag::err_dup_implementation_category) << ClassName 18538a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis << CatName; 18548a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis Diag(CatIDecl->getImplementation()->getLocation(), 18558a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis diag::note_previous_definition); 1856df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis CDecl->setInvalidDecl(); 1857b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian } else { 18588a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis CatIDecl->setImplementation(CDecl); 1859b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian // Warn on implementating category of deprecated class under 1860b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian // -Wdeprecated-implementations flag. 18615ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian DiagnoseObjCImplementedDeprecations(*this, 18625ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian dyn_cast<NamedDecl>(IDecl), 18635ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian CDecl->getLocation(), 2); 1864b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian } 18658a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis } 18661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 186715281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson CheckObjCDeclScope(CDecl); 18683a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis return ActOnObjCContainerStartDefinition(CDecl); 18694d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 18704d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 1871d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema::ActOnStartClassImplementation( 18724d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner SourceLocation AtClassImplLoc, 18734d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner IdentifierInfo *ClassName, SourceLocation ClassLoc, 18741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump IdentifierInfo *SuperClassname, 18754d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner SourceLocation SuperClassLoc) { 18766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ObjCInterfaceDecl *IDecl = nullptr; 18774d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check for another declaration kind with the same name. 1878f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *PrevDecl 1879c0b39640de335809ca7544f802751112619f30ccDouglas Gregor = LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName, 1880c0b39640de335809ca7544f802751112619f30ccDouglas Gregor ForRedeclaration); 1881a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) { 18823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName; 18835f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(PrevDecl->getLocation(), diag::note_previous_definition); 1884deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor } else if ((IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))) { 188587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // FIXME: This will produce an error if the definition of the interface has 188687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // been imported from a module but is not visible. 18870af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), 18880af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor diag::warn_undef_interface); 188995ff742380d1c3dd5152739183bfe085cf27197fDouglas Gregor } else { 18902d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith // We did not find anything with the name ClassName; try to correct for 189195ff742380d1c3dd5152739183bfe085cf27197fDouglas Gregor // typos in the class name. 1892176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TypoCorrection Corrected = CorrectTypo( 1893176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines DeclarationNameInfo(ClassName, ClassLoc), LookupOrdinaryName, TUScope, 1894176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines nullptr, llvm::make_unique<ObjCInterfaceValidatorCCC>(), CTK_NonError); 18952d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith if (Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) { 18962d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith // Suggest the (potentially) correct interface name. Don't provide a 18972d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith // code-modification hint or use the typo name for recovery, because 18982d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith // this is just a warning. The program may actually be correct. 18992d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith diagnoseTypo(Corrected, 19002d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith PDiag(diag::warn_undef_interface_suggest) << ClassName, 19012d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith /*ErrorRecovery*/false); 190295ff742380d1c3dd5152739183bfe085cf27197fDouglas Gregor } else { 190395ff742380d1c3dd5152739183bfe085cf27197fDouglas Gregor Diag(ClassLoc, diag::warn_undef_interface) << ClassName; 190495ff742380d1c3dd5152739183bfe085cf27197fDouglas Gregor } 19054d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 19061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19074d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check that super class name is valid class name 19086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ObjCInterfaceDecl *SDecl = nullptr; 19094d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (SuperClassname) { 19104d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check if a different kind of symbol declared in this scope. 1911c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor PrevDecl = LookupSingleName(TUScope, SuperClassname, SuperClassLoc, 1912c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor LookupOrdinaryName); 1913a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) { 19143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(SuperClassLoc, diag::err_redefinition_different_kind) 19153c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << SuperClassname; 19165f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(PrevDecl->getLocation(), diag::note_previous_definition); 19173c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner } else { 19181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump SDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl); 1919cd707abbc758149d9f7d37bd0b25298455c678b2Argyrios Kyrtzidis if (SDecl && !SDecl->hasDefinition()) 19206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SDecl = nullptr; 19214d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (!SDecl) 19223c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(SuperClassLoc, diag::err_undef_superclass) 19233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << SuperClassname << ClassName; 192460ef308e51c71b760d7f598c1b763ceb7b768148Douglas Gregor else if (IDecl && !declaresSameEntity(IDecl->getSuperClass(), SDecl)) { 19254d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // This implementation and its interface do not have the same 19264d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // super class. 19273c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(SuperClassLoc, diag::err_conflicting_super_class) 192808631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << SDecl->getDeclName(); 19295f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(SDecl->getLocation(), diag::note_previous_definition); 19304d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 19314d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 19324d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 19331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19344d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (!IDecl) { 19354d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Legacy case of @implementation with no corresponding @interface. 19364d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Build, chain & install the interface decl into the identifier. 1937f6414927e67e27d9324d8d179c5f7ea620443924Daniel Dunbar 1938390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Do we support attributes on the @implementation? If so we should 1939390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // copy them over. 19401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc, 194187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ClassName, /*typeParamList=*/nullptr, 194287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /*PrevDecl=*/nullptr, ClassLoc, 19430af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor true); 19442e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor IDecl->startDefinition(); 194505c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor if (SDecl) { 194687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar IDecl->setSuperClass(Context.getTrivialTypeSourceInfo( 194787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Context.getObjCInterfaceType(SDecl), 194887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SuperClassLoc)); 194905c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor IDecl->setEndOfDefinitionLoc(SuperClassLoc); 195005c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor } else { 195105c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor IDecl->setEndOfDefinitionLoc(ClassLoc); 195205c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor } 195305c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor 19548b9fb3082bc54cf7ffe6c3772500a73388f53072Douglas Gregor PushOnScopeChains(IDecl, TUScope); 1955deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor } else { 1956deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor // Mark the interface as being completed, even if it was just as 1957deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor // @class ....; 1958deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor // declaration; the user cannot reopen it. 19592e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor if (!IDecl->hasDefinition()) 19602e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor IDecl->startDefinition(); 19614d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 19621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCImplementationDecl* IMPDecl = 19641711fc91efb36d131f7ba771f73f0154dc1abd1fArgyrios Kyrtzidis ObjCImplementationDecl::Create(Context, CurContext, IDecl, SDecl, 1965634c5634817b9ad384a706fe87ab302985566bbaArgyrios Kyrtzidis ClassLoc, AtClassImplLoc, SuperClassLoc); 19661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 196715281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson if (CheckObjCDeclScope(IMPDecl)) 19683a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis return ActOnObjCContainerStartDefinition(IMPDecl); 19691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19704d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check that there is no duplicate implementation of this class. 1971deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor if (IDecl->getImplementation()) { 1972deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor // FIXME: Don't leak everything! 19733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName; 197487018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis Diag(IDecl->getImplementation()->getLocation(), 197587018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis diag::note_previous_definition); 1976df08c4b371522025d1d3aec4992fb0f27d7c4571Argyrios Kyrtzidis IMPDecl->setInvalidDecl(); 1977deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor } else { // add it to the list. 19788a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis IDecl->setImplementation(IMPDecl); 19798fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor PushOnScopeChains(IMPDecl, TUScope); 1980b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian // Warn on implementating deprecated class under 1981b1224f69089815fd66b04ae33215b7fba10780aaFariborz Jahanian // -Wdeprecated-implementations flag. 19825ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian DiagnoseObjCImplementedDeprecations(*this, 19835ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian dyn_cast<NamedDecl>(IDecl), 19845ac96d5f54a94d57f485de8103eb05a0f19e1c39Fariborz Jahanian IMPDecl->getLocation(), 1); 19858a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis } 19864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 19874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // If the superclass has the objc_runtime_visible attribute, we 19884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // cannot implement a subclass of it. 19894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (IDecl->getSuperClass() && 19904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar IDecl->getSuperClass()->hasAttr<ObjCRuntimeVisibleAttr>()) { 19914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Diag(ClassLoc, diag::err_objc_runtime_visible_subclass) 19924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar << IDecl->getDeclName() 19934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar << IDecl->getSuperClass()->getDeclName(); 19944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 19954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 19963a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis return ActOnObjCContainerStartDefinition(IMPDecl); 19974d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 19984d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 1999644af7b50bd0541468b45c197f5b637e934d48a0Argyrios KyrtzidisSema::DeclGroupPtrTy 2000644af7b50bd0541468b45c197f5b637e934d48a0Argyrios KyrtzidisSema::ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef<Decl *> Decls) { 2001644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis SmallVector<Decl *, 64> DeclsInGroup; 2002644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis DeclsInGroup.reserve(Decls.size() + 1); 2003644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis 2004644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis for (unsigned i = 0, e = Decls.size(); i != e; ++i) { 2005644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis Decl *Dcl = Decls[i]; 2006644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis if (!Dcl) 2007644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis continue; 2008644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis if (Dcl->getDeclContext()->isFileContext()) 2009644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis Dcl->setTopLevelDeclInObjCContainer(); 2010644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis DeclsInGroup.push_back(Dcl); 2011644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis } 2012644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis 2013644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis DeclsInGroup.push_back(ObjCImpDecl); 2014644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis 20154549d7ffc15bdd7ab860aa68db089d9f559b79e7Rafael Espindola return BuildDeclaratorGroup(DeclsInGroup, false); 2016644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis} 2017644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis 2018a526c5c67e5a0473c340903ee542ce570119665fTed Kremenekvoid Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, 2019a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek ObjCIvarDecl **ivars, unsigned numIvars, 20204d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner SourceLocation RBrace) { 20214d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner assert(ImpDecl && "missing implementation decl"); 20224afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor ObjCInterfaceDecl* IDecl = ImpDecl->getClassInterface(); 20234d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (!IDecl) 20244d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner return; 20251dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett /// Check case of non-existing \@interface decl. 20261dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett /// (legacy objective-c \@implementation decl without an \@interface decl). 20274d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner /// Add implementations's ivar to the synthesize class's ivar list. 202833feeb019a5742b286eededd5446ec0fe87c5a61Steve Naroff if (IDecl->isImplicitInterfaceDecl()) { 202905c272fed899b8d3142cf080e86a235fc6168862Douglas Gregor IDecl->setEndOfDefinitionLoc(RBrace); 20303a21cd92f425680fcbfbab9552c0787b09ae9ca7Fariborz Jahanian // Add ivar's to class's DeclContext. 20313a21cd92f425680fcbfbab9552c0787b09ae9ca7Fariborz Jahanian for (unsigned i = 0, e = numIvars; i != e; ++i) { 20322f14c4d18fcba4b4577dbe43016d6d42ef9973cfFariborz Jahanian ivars[i]->setLexicalDeclContext(ImpDecl); 20331b7f9cbed1b96b58a6e5f7808ebc9345a76a0936Richard Smith IDecl->makeDeclVisibleInContext(ivars[i]); 203411062e11236b7bc689dad150e8b490fd6b063ec3Fariborz Jahanian ImpDecl->addDecl(ivars[i]); 20353a21cd92f425680fcbfbab9552c0787b09ae9ca7Fariborz Jahanian } 20363a21cd92f425680fcbfbab9552c0787b09ae9ca7Fariborz Jahanian 20374d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner return; 20384d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 20394d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // If implementation has empty ivar list, just return. 20404d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (numIvars == 0) 20414d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner return; 20421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20434d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner assert(ivars && "missing @implementation ivars"); 2044260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (LangOpts.ObjCRuntime.isNonFragile()) { 2045bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian if (ImpDecl->getSuperClass()) 2046bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian Diag(ImpDecl->getLocation(), diag::warn_on_superclass_use); 2047bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian for (unsigned i = 0; i < numIvars; i++) { 2048bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian ObjCIvarDecl* ImplIvar = ivars[i]; 2049bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian if (const ObjCIvarDecl *ClsIvar = 2050bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian IDecl->getIvarDecl(ImplIvar->getIdentifier())) { 2051bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration); 2052bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian Diag(ClsIvar->getLocation(), diag::note_previous_definition); 2053bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian continue; 2054bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian } 20553b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian // Check class extensions (unnamed categories) for duplicate ivars. 2056651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *CDecl : IDecl->visible_extensions()) { 20573b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian if (const ObjCIvarDecl *ClsExtIvar = 20583b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian CDecl->getIvarDecl(ImplIvar->getIdentifier())) { 20593b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration); 20603b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian Diag(ClsExtIvar->getLocation(), diag::note_previous_definition); 20613b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian continue; 20623b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian } 20633b20f581de2ddd824ef86114ff65fcf37fe02973Fariborz Jahanian } 2064bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian // Instance ivar to Implementation's DeclContext. 2065bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian ImplIvar->setLexicalDeclContext(ImpDecl); 20661b7f9cbed1b96b58a6e5f7808ebc9345a76a0936Richard Smith IDecl->makeDeclVisibleInContext(ImplIvar); 2067bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian ImpDecl->addDecl(ImplIvar); 2068bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian } 2069bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian return; 2070bd94d442f6801a4d2a25d53c1843690533180a6dFariborz Jahanian } 20714d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check interface's Ivar list against those in the implementation. 20724d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // names and types must match. 20734d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // 20744d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner unsigned j = 0; 20751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCInterfaceDecl::ivar_iterator 20764c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner IVI = IDecl->ivar_begin(), IVE = IDecl->ivar_end(); 20774c52509ffb9fdd6c93aa7b50812e316f1d920a26Chris Lattner for (; numIvars > 0 && IVI != IVE; ++IVI) { 2078a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek ObjCIvarDecl* ImplIvar = ivars[j++]; 2079581deb3da481053c4993c7600f97acf7768caac5David Blaikie ObjCIvarDecl* ClsIvar = *IVI; 20804d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner assert (ImplIvar && "missing implementation ivar"); 20814d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner assert (ClsIvar && "missing class ivar"); 20821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2083ca33129bb28b05938c3e6c9f8a66165b5cceb4ddSteve Naroff // First, make sure the types match. 2084a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith if (!Context.hasSameType(ImplIvar->getType(), ClsIvar->getType())) { 2085fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type) 208608631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << ImplIvar->getIdentifier() 208708631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << ImplIvar->getType() << ClsIvar->getType(); 20885f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(ClsIvar->getLocation(), diag::note_previous_definition); 2089a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith } else if (ImplIvar->isBitField() && ClsIvar->isBitField() && 2090a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith ImplIvar->getBitWidthValue(Context) != 2091a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith ClsIvar->getBitWidthValue(Context)) { 2092a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith Diag(ImplIvar->getBitWidth()->getLocStart(), 2093a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith diag::err_conflicting_ivar_bitwidth) << ImplIvar->getIdentifier(); 2094a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith Diag(ClsIvar->getBitWidth()->getLocStart(), 2095a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith diag::note_previous_definition); 20961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 2097ca33129bb28b05938c3e6c9f8a66165b5cceb4ddSteve Naroff // Make sure the names are identical. 2098ca33129bb28b05938c3e6c9f8a66165b5cceb4ddSteve Naroff if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) { 2099fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name) 210008631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << ImplIvar->getIdentifier() << ClsIvar->getIdentifier(); 21015f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(ClsIvar->getLocation(), diag::note_previous_definition); 21024d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 21034d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner --numIvars; 21044d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 21051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2106609e4c72d9190a57636836d658b3563d9a9545aeChris Lattner if (numIvars > 0) 2107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diag(ivars[j]->getLocation(), diag::err_inconsistent_ivar_count); 2108609e4c72d9190a57636836d658b3563d9a9545aeChris Lattner else if (IVI != IVE) 2109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diag(IVI->getLocation(), diag::err_inconsistent_ivar_count); 21104d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 21114d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 2112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void WarnUndefinedMethod(Sema &S, SourceLocation ImpLoc, 2113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCMethodDecl *method, 2114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool &IncompleteImpl, 2115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned DiagID, 21166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines NamedDecl *NeededFor = nullptr) { 2117327126ee3d2faad9314b2633974eefc672f73b79Fariborz Jahanian // No point warning no definition of method which is 'unavailable'. 211886f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor switch (method->getAvailability()) { 211986f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor case AR_Available: 212086f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor case AR_Deprecated: 212186f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor break; 212286f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor 212386f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor // Don't warn about unavailable or not-yet-introduced methods. 212486f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor case AR_NotYetIntroduced: 212586f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor case AR_Unavailable: 2126327126ee3d2faad9314b2633974eefc672f73b79Fariborz Jahanian return; 212786f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor } 212886f6cf6800fa7ea3669e057c56f3487c4da3ef46Douglas Gregor 21298b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek // FIXME: For now ignore 'IncompleteImpl'. 21308b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek // Previously we grouped all unimplemented methods under a single 21318b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek // warning, but some users strongly voiced that they would prefer 21328b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek // separate warnings. We will give that approach a try, as that 21338b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek // matches what we do with protocols. 2134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines { 2135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Sema::SemaDiagnosticBuilder &B = S.Diag(ImpLoc, DiagID); 2136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B << method; 2137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (NeededFor) 2138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B << NeededFor; 2139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 21408b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek 21418b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek // Issue a note to the original declaration. 21428b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek SourceLocation MethodLoc = method->getLocStart(); 21438b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek if (MethodLoc.isValid()) 2144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.Diag(MethodLoc, diag::note_method_declared_at) << method; 21453c2eb66b0acb13c4bdd628e5e148c37958a85ec4Steve Naroff} 21463c2eb66b0acb13c4bdd628e5e148c37958a85ec4Steve Naroff 2147e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// Determines if type B can be substituted for type A. Returns true if we can 2148e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// guarantee that anything that the user will do to an object of type A can 2149e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// also be done to an object of type B. This is trivially true if the two 2150e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// types are the same, or if B is a subclass of A. It becomes more complex 2151e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// in cases where protocols are involved. 2152e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// 2153e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// Object types in Objective-C describe the minimum requirements for an 2154e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// object, rather than providing a complete description of a type. For 2155e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// example, if A is a subclass of B, then B* may refer to an instance of A. 2156e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// The principle of substitutability means that we may use an instance of A 2157e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// anywhere that we may use an instance of B - it will implement all of the 2158e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// ivars of B and all of the methods of B. 2159e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// 2160e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// This substitutability is important when type checking methods, because 2161e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// the implementation may have stricter type definitions than the interface. 2162e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// The interface specifies minimum requirements, but the implementation may 2163e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// have more accurate ones. For example, a method may privately accept 2164e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// instances of B, but only publish that it accepts instances of A. Any 2165e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// object passed to it will be type checked against B, and so will implicitly 2166e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// by a valid A*. Similarly, a method may return a subclass of the class that 2167e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// it is declared as returning. 2168e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// 2169e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// This is most important when considering subclassing. A method in a 2170e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// subclass must accept any object as an argument that its superclass's 2171e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// implementation accepts. It may, however, accept a more general type 2172e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// without breaking substitutability (i.e. you can still use the subclass 2173e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// anywhere that you can use the superclass, but not vice versa). The 2174e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// converse requirement applies to return types: the return type for a 2175e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// subclass method must be a valid object of the kind that the superclass 2176e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// advertises, but it may be specified more accurately. This avoids the need 2177e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// for explicit down-casting by callers. 2178e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// 2179e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall/// Note: This is a stricter requirement than for assignment. 218010302c01e8ceffd86c1a2b1bb15466e852ca8898John McCallstatic bool isObjCTypeSubstitutable(ASTContext &Context, 218110302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall const ObjCObjectPointerType *A, 218210302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall const ObjCObjectPointerType *B, 218310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall bool rejectId) { 218410302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // Reject a protocol-unqualified id. 218510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall if (rejectId && B->isObjCIdType()) return false; 2186e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall 2187e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // If B is a qualified id, then A must also be a qualified id and it must 2188e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // implement all of the protocols in B. It may not be a qualified class. 2189e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // For example, MyClass<A> can be assigned to id<A>, but MyClass<A> is a 2190e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // stricter definition so it is not substitutable for id<A>. 2191e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall if (B->isObjCQualifiedIdType()) { 2192e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall return A->isObjCQualifiedIdType() && 219310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall Context.ObjCQualifiedIdTypesAreCompatible(QualType(A, 0), 219410302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall QualType(B,0), 219510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall false); 2196e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall } 2197e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall 2198e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall /* 2199e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // id is a special type that bypasses type checking completely. We want a 2200e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // warning when it is used in one place but not another. 2201e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall if (C.isObjCIdType(A) || C.isObjCIdType(B)) return false; 2202e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall 2203e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall 2204e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // If B is a qualified id, then A must also be a qualified id (which it isn't 2205e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // if we've got this far) 2206e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall if (B->isObjCQualifiedIdType()) return false; 2207e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall */ 2208e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall 2209e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // Now we know that A and B are (potentially-qualified) class types. The 2210e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall // normal rules for assignment apply. 221110302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall return Context.canAssignObjCInterfaces(A, B); 2212e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall} 2213e8a2d4c32cb2a7840bd91c9cf9b7838ee3f47dc3David Chisnall 221410302c01e8ceffd86c1a2b1bb15466e852ca8898John McCallstatic SourceRange getTypeRange(TypeSourceInfo *TSI) { 221510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall return (TSI ? TSI->getTypeLoc().getSourceRange() : SourceRange()); 221610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall} 221710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 221887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// Determine whether two set of Objective-C declaration qualifiers conflict. 221987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstatic bool objcModifiersConflict(Decl::ObjCDeclQualifier x, 222087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Decl::ObjCDeclQualifier y) { 222187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return (x & ~Decl::OBJC_TQ_CSNullability) != 222287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar (y & ~Decl::OBJC_TQ_CSNullability); 222387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} 222487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 2225fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanianstatic bool CheckMethodOverrideReturn(Sema &S, 222610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall ObjCMethodDecl *MethodImpl, 222721761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian ObjCMethodDecl *MethodDecl, 2228eee3ef177a171c06f826c331e7a9e256d01eaeb0Fariborz Jahanian bool IsProtocolMethodDecl, 2229730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian bool IsOverridingMode, 2230fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian bool Warn) { 223121761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian if (IsProtocolMethodDecl && 223287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar objcModifiersConflict(MethodDecl->getObjCDeclQualifier(), 223387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar MethodImpl->getObjCDeclQualifier())) { 2234fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (Warn) { 2235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.Diag(MethodImpl->getLocation(), 2236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (IsOverridingMode 2237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ? diag::warn_conflicting_overriding_ret_type_modifiers 2238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : diag::warn_conflicting_ret_type_modifiers)) 2239730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian << MethodImpl->getDeclName() 2240176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines << MethodImpl->getReturnTypeSourceRange(); 2241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration) 2242176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines << MethodDecl->getReturnTypeSourceRange(); 2243fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian } 2244fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian else 2245fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return false; 224621761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian } 224787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (Warn && IsOverridingMode && 224887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar !isa<ObjCImplementationDecl>(MethodImpl->getDeclContext()) && 224987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar !S.Context.hasSameNullabilityTypeQualifier(MethodImpl->getReturnType(), 225087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar MethodDecl->getReturnType(), 225187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar false)) { 225287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto nullabilityMethodImpl = 225387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar *MethodImpl->getReturnType()->getNullability(S.Context); 225487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto nullabilityMethodDecl = 225587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar *MethodDecl->getReturnType()->getNullability(S.Context); 225687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Diag(MethodImpl->getLocation(), 225787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diag::warn_conflicting_nullability_attr_overriding_ret_types) 225887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << DiagNullabilityKind( 225987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar nullabilityMethodImpl, 226087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ((MethodImpl->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) 226187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar != 0)) 226287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << DiagNullabilityKind( 226387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar nullabilityMethodDecl, 226487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ((MethodDecl->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) 226587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar != 0)); 226687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration); 226787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 226887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 2269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (S.Context.hasSameUnqualifiedType(MethodImpl->getReturnType(), 2270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MethodDecl->getReturnType())) 2271fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return true; 2272fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (!Warn) 2273fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return false; 227410302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 2275730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian unsigned DiagID = 2276730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian IsOverridingMode ? diag::warn_conflicting_overriding_ret_types 2277730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian : diag::warn_conflicting_ret_types; 227810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 227910302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // Mismatches between ObjC pointers go into a different warning 228010302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // category, and sometimes they're even completely whitelisted. 228110302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall if (const ObjCObjectPointerType *ImplPtrTy = 2282651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MethodImpl->getReturnType()->getAs<ObjCObjectPointerType>()) { 228310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall if (const ObjCObjectPointerType *IfacePtrTy = 2284651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MethodDecl->getReturnType()->getAs<ObjCObjectPointerType>()) { 228510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // Allow non-matching return types as long as they don't violate 228610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // the principle of substitutability. Specifically, we permit 228710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // return types that are subclasses of the declared return type, 228810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // or that are more-qualified versions of the declared type. 228910302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall if (isObjCTypeSubstitutable(S.Context, IfacePtrTy, ImplPtrTy, false)) 2290fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return false; 229110302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 2292730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian DiagID = 2293730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian IsOverridingMode ? diag::warn_non_covariant_overriding_ret_types 229487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : diag::warn_non_covariant_ret_types; 229510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall } 229610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall } 229710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 229810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall S.Diag(MethodImpl->getLocation(), DiagID) 2299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << MethodImpl->getDeclName() << MethodDecl->getReturnType() 2300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << MethodImpl->getReturnType() 2301176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines << MethodImpl->getReturnTypeSourceRange(); 2302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.Diag(MethodDecl->getLocation(), IsOverridingMode 2303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ? diag::note_previous_declaration 2304651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : diag::note_previous_definition) 2305176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines << MethodDecl->getReturnTypeSourceRange(); 2306fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return false; 230710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall} 230810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 2309fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanianstatic bool CheckMethodOverrideParam(Sema &S, 231010302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall ObjCMethodDecl *MethodImpl, 231121761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian ObjCMethodDecl *MethodDecl, 231210302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall ParmVarDecl *ImplVar, 231321761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian ParmVarDecl *IfaceVar, 2314eee3ef177a171c06f826c331e7a9e256d01eaeb0Fariborz Jahanian bool IsProtocolMethodDecl, 2315730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian bool IsOverridingMode, 2316fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian bool Warn) { 231721761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian if (IsProtocolMethodDecl && 231887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar objcModifiersConflict(ImplVar->getObjCDeclQualifier(), 231987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar IfaceVar->getObjCDeclQualifier())) { 2320fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (Warn) { 2321730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian if (IsOverridingMode) 2322730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian S.Diag(ImplVar->getLocation(), 2323730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian diag::warn_conflicting_overriding_param_modifiers) 2324730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian << getTypeRange(ImplVar->getTypeSourceInfo()) 2325730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian << MethodImpl->getDeclName(); 2326730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian else S.Diag(ImplVar->getLocation(), 2327fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian diag::warn_conflicting_param_modifiers) 2328fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian << getTypeRange(ImplVar->getTypeSourceInfo()) 2329730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian << MethodImpl->getDeclName(); 2330fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration) 2331fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian << getTypeRange(IfaceVar->getTypeSourceInfo()); 2332fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian } 2333fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian else 2334fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return false; 233521761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian } 233621761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian 233710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall QualType ImplTy = ImplVar->getType(); 233810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall QualType IfaceTy = IfaceVar->getType(); 233987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (Warn && IsOverridingMode && 234087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar !isa<ObjCImplementationDecl>(MethodImpl->getDeclContext()) && 234187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar !S.Context.hasSameNullabilityTypeQualifier(ImplTy, IfaceTy, true)) { 234287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Diag(ImplVar->getLocation(), 234387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diag::warn_conflicting_nullability_attr_overriding_param_types) 234487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << DiagNullabilityKind( 234587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar *ImplTy->getNullability(S.Context), 234687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ((ImplVar->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) 234787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar != 0)) 234887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << DiagNullabilityKind( 234987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar *IfaceTy->getNullability(S.Context), 235087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ((IfaceVar->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) 235187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar != 0)); 235287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration); 235387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 235410302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall if (S.Context.hasSameUnqualifiedType(ImplTy, IfaceTy)) 2355fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return true; 2356fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian 2357fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (!Warn) 2358fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return false; 2359730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian unsigned DiagID = 2360730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian IsOverridingMode ? diag::warn_conflicting_overriding_param_types 2361730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian : diag::warn_conflicting_param_types; 236210302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 236310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // Mismatches between ObjC pointers go into a different warning 236410302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // category, and sometimes they're even completely whitelisted. 236510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall if (const ObjCObjectPointerType *ImplPtrTy = 236610302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall ImplTy->getAs<ObjCObjectPointerType>()) { 236710302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall if (const ObjCObjectPointerType *IfacePtrTy = 236810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall IfaceTy->getAs<ObjCObjectPointerType>()) { 236910302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // Allow non-matching argument types as long as they don't 237010302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // violate the principle of substitutability. Specifically, the 237110302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // implementation must accept any objects that the superclass 237210302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall // accepts, however it may also accept others. 237310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall if (isObjCTypeSubstitutable(S.Context, ImplPtrTy, IfacePtrTy, true)) 2374fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return false; 237510302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 2376730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian DiagID = 2377730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian IsOverridingMode ? diag::warn_non_contravariant_overriding_param_types 237887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : diag::warn_non_contravariant_param_types; 237910302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall } 238010302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall } 238110302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 238210302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall S.Diag(ImplVar->getLocation(), DiagID) 238310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall << getTypeRange(ImplVar->getTypeSourceInfo()) 2384730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian << MethodImpl->getDeclName() << IfaceTy << ImplTy; 2385730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian S.Diag(IfaceVar->getLocation(), 2386730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian (IsOverridingMode ? diag::note_previous_declaration 238787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : diag::note_previous_definition)) 238810302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall << getTypeRange(IfaceVar->getTypeSourceInfo()); 2389fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return false; 239010302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall} 2391f85e193739c953358c865005855253af4f68a497John McCall 2392f85e193739c953358c865005855253af4f68a497John McCall/// In ARC, check whether the conventional meanings of the two methods 2393f85e193739c953358c865005855253af4f68a497John McCall/// match. If they don't, it's a hard error. 2394f85e193739c953358c865005855253af4f68a497John McCallstatic bool checkMethodFamilyMismatch(Sema &S, ObjCMethodDecl *impl, 2395f85e193739c953358c865005855253af4f68a497John McCall ObjCMethodDecl *decl) { 2396f85e193739c953358c865005855253af4f68a497John McCall ObjCMethodFamily implFamily = impl->getMethodFamily(); 2397f85e193739c953358c865005855253af4f68a497John McCall ObjCMethodFamily declFamily = decl->getMethodFamily(); 2398f85e193739c953358c865005855253af4f68a497John McCall if (implFamily == declFamily) return false; 2399f85e193739c953358c865005855253af4f68a497John McCall 2400f85e193739c953358c865005855253af4f68a497John McCall // Since conventions are sorted by selector, the only possibility is 2401f85e193739c953358c865005855253af4f68a497John McCall // that the types differ enough to cause one selector or the other 2402f85e193739c953358c865005855253af4f68a497John McCall // to fall out of the family. 2403f85e193739c953358c865005855253af4f68a497John McCall assert(implFamily == OMF_None || declFamily == OMF_None); 2404f85e193739c953358c865005855253af4f68a497John McCall 2405f85e193739c953358c865005855253af4f68a497John McCall // No further diagnostics required on invalid declarations. 2406f85e193739c953358c865005855253af4f68a497John McCall if (impl->isInvalidDecl() || decl->isInvalidDecl()) return true; 2407f85e193739c953358c865005855253af4f68a497John McCall 2408f85e193739c953358c865005855253af4f68a497John McCall const ObjCMethodDecl *unmatched = impl; 2409f85e193739c953358c865005855253af4f68a497John McCall ObjCMethodFamily family = declFamily; 2410f85e193739c953358c865005855253af4f68a497John McCall unsigned errorID = diag::err_arc_lost_method_convention; 2411f85e193739c953358c865005855253af4f68a497John McCall unsigned noteID = diag::note_arc_lost_method_convention; 2412f85e193739c953358c865005855253af4f68a497John McCall if (declFamily == OMF_None) { 2413f85e193739c953358c865005855253af4f68a497John McCall unmatched = decl; 2414f85e193739c953358c865005855253af4f68a497John McCall family = implFamily; 2415f85e193739c953358c865005855253af4f68a497John McCall errorID = diag::err_arc_gained_method_convention; 2416f85e193739c953358c865005855253af4f68a497John McCall noteID = diag::note_arc_gained_method_convention; 2417f85e193739c953358c865005855253af4f68a497John McCall } 2418f85e193739c953358c865005855253af4f68a497John McCall 2419f85e193739c953358c865005855253af4f68a497John McCall // Indexes into a %select clause in the diagnostic. 2420f85e193739c953358c865005855253af4f68a497John McCall enum FamilySelector { 2421f85e193739c953358c865005855253af4f68a497John McCall F_alloc, F_copy, F_mutableCopy = F_copy, F_init, F_new 2422f85e193739c953358c865005855253af4f68a497John McCall }; 2423f85e193739c953358c865005855253af4f68a497John McCall FamilySelector familySelector = FamilySelector(); 2424f85e193739c953358c865005855253af4f68a497John McCall 2425f85e193739c953358c865005855253af4f68a497John McCall switch (family) { 2426f85e193739c953358c865005855253af4f68a497John McCall case OMF_None: llvm_unreachable("logic error, no method convention"); 2427f85e193739c953358c865005855253af4f68a497John McCall case OMF_retain: 2428f85e193739c953358c865005855253af4f68a497John McCall case OMF_release: 2429f85e193739c953358c865005855253af4f68a497John McCall case OMF_autorelease: 2430f85e193739c953358c865005855253af4f68a497John McCall case OMF_dealloc: 243180cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber case OMF_finalize: 2432f85e193739c953358c865005855253af4f68a497John McCall case OMF_retainCount: 2433f85e193739c953358c865005855253af4f68a497John McCall case OMF_self: 2434176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case OMF_initialize: 24359670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian case OMF_performSelector: 2436f85e193739c953358c865005855253af4f68a497John McCall // Mismatches for these methods don't change ownership 2437f85e193739c953358c865005855253af4f68a497John McCall // conventions, so we don't care. 2438f85e193739c953358c865005855253af4f68a497John McCall return false; 2439f85e193739c953358c865005855253af4f68a497John McCall 2440f85e193739c953358c865005855253af4f68a497John McCall case OMF_init: familySelector = F_init; break; 2441f85e193739c953358c865005855253af4f68a497John McCall case OMF_alloc: familySelector = F_alloc; break; 2442f85e193739c953358c865005855253af4f68a497John McCall case OMF_copy: familySelector = F_copy; break; 2443f85e193739c953358c865005855253af4f68a497John McCall case OMF_mutableCopy: familySelector = F_mutableCopy; break; 2444f85e193739c953358c865005855253af4f68a497John McCall case OMF_new: familySelector = F_new; break; 2445f85e193739c953358c865005855253af4f68a497John McCall } 2446f85e193739c953358c865005855253af4f68a497John McCall 2447f85e193739c953358c865005855253af4f68a497John McCall enum ReasonSelector { R_NonObjectReturn, R_UnrelatedReturn }; 2448f85e193739c953358c865005855253af4f68a497John McCall ReasonSelector reasonSelector; 2449f85e193739c953358c865005855253af4f68a497John McCall 2450f85e193739c953358c865005855253af4f68a497John McCall // The only reason these methods don't fall within their families is 2451f85e193739c953358c865005855253af4f68a497John McCall // due to unusual result types. 2452651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (unmatched->getReturnType()->isObjCObjectPointerType()) { 2453f85e193739c953358c865005855253af4f68a497John McCall reasonSelector = R_UnrelatedReturn; 2454f85e193739c953358c865005855253af4f68a497John McCall } else { 2455f85e193739c953358c865005855253af4f68a497John McCall reasonSelector = R_NonObjectReturn; 2456f85e193739c953358c865005855253af4f68a497John McCall } 2457f85e193739c953358c865005855253af4f68a497John McCall 24587348454025693dd20a411c2bcaabd4460cb87559Joerg Sonnenberger S.Diag(impl->getLocation(), errorID) << int(familySelector) << int(reasonSelector); 24597348454025693dd20a411c2bcaabd4460cb87559Joerg Sonnenberger S.Diag(decl->getLocation(), noteID) << int(familySelector) << int(reasonSelector); 2460f85e193739c953358c865005855253af4f68a497John McCall 2461f85e193739c953358c865005855253af4f68a497John McCall return true; 2462f85e193739c953358c865005855253af4f68a497John McCall} 246310302c01e8ceffd86c1a2b1bb15466e852ca8898John McCall 24648daab970b80ed2e751fc88327180acbeff1dbb9cFariborz Jahanianvoid Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl, 246521761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian ObjCMethodDecl *MethodDecl, 246636bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian bool IsProtocolMethodDecl) { 24674e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjCAutoRefCount && 2468f85e193739c953358c865005855253af4f68a497John McCall checkMethodFamilyMismatch(*this, ImpMethodDecl, MethodDecl)) 2469f85e193739c953358c865005855253af4f68a497John McCall return; 2470f85e193739c953358c865005855253af4f68a497John McCall 247121761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl, 247236bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian IsProtocolMethodDecl, false, 2473730cfb18463d8c2f6d0e4d4380fdd67e4abe5d97Fariborz Jahanian true); 24741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 24753aff919532fd807ed678b9cfa4b7eca7b04adcf9Chris Lattner for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(), 24760a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(), 24770a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor EF = MethodDecl->param_end(); 24780a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor IM != EM && IF != EF; ++IM, ++IF) { 247921761c8378a493c32ab0f7d2b8880986a0ba73a3Fariborz Jahanian CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl, *IM, *IF, 248036bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian IsProtocolMethodDecl, false, true); 2481561da7e046ea6b39f4e632c68128fd01c985b46bFariborz Jahanian } 24828daab970b80ed2e751fc88327180acbeff1dbb9cFariborz Jahanian 24832112190efa85f50af84a3c4efe03c5bf69247ba2Fariborz Jahanian if (ImpMethodDecl->isVariadic() != MethodDecl->isVariadic()) { 248436bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian Diag(ImpMethodDecl->getLocation(), 248536bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian diag::warn_conflicting_variadic); 24862112190efa85f50af84a3c4efe03c5bf69247ba2Fariborz Jahanian Diag(MethodDecl->getLocation(), diag::note_previous_declaration); 24872112190efa85f50af84a3c4efe03c5bf69247ba2Fariborz Jahanian } 24882112190efa85f50af84a3c4efe03c5bf69247ba2Fariborz Jahanian} 24892112190efa85f50af84a3c4efe03c5bf69247ba2Fariborz Jahanian 249036bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanianvoid Sema::CheckConflictingOverridingMethod(ObjCMethodDecl *Method, 249136bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian ObjCMethodDecl *Overridden, 249236bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian bool IsProtocolMethodDecl) { 249336bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian 249436bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian CheckMethodOverrideReturn(*this, Method, Overridden, 249536bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian IsProtocolMethodDecl, true, 249636bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian true); 249736bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian 249836bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian for (ObjCMethodDecl::param_iterator IM = Method->param_begin(), 24990a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor IF = Overridden->param_begin(), EM = Method->param_end(), 25000a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor EF = Overridden->param_end(); 25010a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor IM != EM && IF != EF; ++IM, ++IF) { 250236bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian CheckMethodOverrideParam(*this, Method, Overridden, *IM, *IF, 250336bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian IsProtocolMethodDecl, true, true); 250436bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian } 250536bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian 250636bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian if (Method->isVariadic() != Overridden->isVariadic()) { 250736bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian Diag(Method->getLocation(), 250836bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian diag::warn_conflicting_overriding_variadic); 250936bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian Diag(Overridden->getLocation(), diag::note_previous_declaration); 251036bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian } 251136bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian} 251236bc2c663f600e7c9dc1a800d36f16603ca3ea51Fariborz Jahanian 2513fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian/// WarnExactTypedMethods - This routine issues a warning if method 2514fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian/// implementation declaration matches exactly that of its declaration. 2515fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanianvoid Sema::WarnExactTypedMethods(ObjCMethodDecl *ImpMethodDecl, 2516fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian ObjCMethodDecl *MethodDecl, 2517fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian bool IsProtocolMethodDecl) { 2518fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // don't issue warning when protocol method is optional because primary 2519fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // class is not required to implement it and it is safe for protocol 2520fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // to implement it. 2521fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (MethodDecl->getImplementationControl() == ObjCMethodDecl::Optional) 2522fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return; 2523fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // don't issue warning when primary class's method is 2524fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // depecated/unavailable. 2525fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (MethodDecl->hasAttr<UnavailableAttr>() || 2526fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian MethodDecl->hasAttr<DeprecatedAttr>()) 2527fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return; 2528fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian 2529fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian bool match = CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl, 2530fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian IsProtocolMethodDecl, false, false); 2531fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (match) 2532fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(), 25330a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end(), 25340a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor EF = MethodDecl->param_end(); 25350a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor IM != EM && IF != EF; ++IM, ++IF) { 2536fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian match = CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl, 2537fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian *IM, *IF, 2538fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian IsProtocolMethodDecl, false, false); 2539fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (!match) 2540fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian break; 2541fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian } 2542fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (match) 2543fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian match = (ImpMethodDecl->isVariadic() == MethodDecl->isVariadic()); 25447ca13ef64136929df852c038ebbddee070dc5119David Chisnall if (match) 25457ca13ef64136929df852c038ebbddee070dc5119David Chisnall match = !(MethodDecl->isClassMethod() && 25467ca13ef64136929df852c038ebbddee070dc5119David Chisnall MethodDecl->getSelector() == GetNullarySelector("load", Context)); 2547fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian 2548fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (match) { 2549fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian Diag(ImpMethodDecl->getLocation(), 2550fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian diag::warn_category_method_impl_match); 25513306ec1923973d7b5767b23ba95915af2fec87d7Ted Kremenek Diag(MethodDecl->getLocation(), diag::note_method_declared_at) 25523306ec1923973d7b5767b23ba95915af2fec87d7Ted Kremenek << MethodDecl->getDeclName(); 2553fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian } 2554fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian} 2555fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian 2556390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump/// FIXME: Type hierarchies in Objective-C can be deep. We could most likely 2557390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump/// improve the efficiency of selector lookups and type checking by associating 2558390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump/// with each protocol / interface / category the flattened instance tables. If 2559390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump/// we used an immutable set to keep the table then it wouldn't add significant 2560390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump/// memory cost and it would be handy for lookups. 2561b20ef3e3fbe0fabe213dc0149011e9f0d751a3a4Daniel Dunbar 2562651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef llvm::DenseSet<IdentifierInfo*> ProtocolNameSet; 2563651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef std::unique_ptr<ProtocolNameSet> LazyProtocolNameSet; 2564651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void findProtocolsWithExplicitImpls(const ObjCProtocolDecl *PDecl, 2566651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ProtocolNameSet &PNS) { 2567651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (PDecl->hasAttr<ObjCExplicitProtocolImplAttr>()) 2568651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PNS.insert(PDecl->getIdentifier()); 2569651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *PI : PDecl->protocols()) 2570651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines findProtocolsWithExplicitImpls(PI, PNS); 2571651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 2572651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2573651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Recursively populates a set with all conformed protocols in a class 2574651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// hierarchy that have the 'objc_protocol_requires_explicit_implementation' 2575651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// attribute. 2576651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void findProtocolsWithExplicitImpls(const ObjCInterfaceDecl *Super, 2577651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ProtocolNameSet &PNS) { 2578651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!Super) 2579651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 2580651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2581651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *I : Super->all_referenced_protocols()) 2582651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines findProtocolsWithExplicitImpls(I, PNS); 2583651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2584651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines findProtocolsWithExplicitImpls(Super->getSuperClass(), PNS); 2585651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 2586651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2587efe7f36f4d87b6e64b87128a81018350b2f21987Steve Naroff/// CheckProtocolMethodDefs - This routine checks unimplemented methods 25884d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// Declared in protocol, and those referenced by it. 2589651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void CheckProtocolMethodDefs(Sema &S, 2590651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation ImpLoc, 2591651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCProtocolDecl *PDecl, 2592651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool& IncompleteImpl, 2593651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Sema::SelectorSet &InsMap, 2594651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Sema::SelectorSet &ClsMap, 2595651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCContainerDecl *CDecl, 2596651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LazyProtocolNameSet &ProtocolsExplictImpl) { 2597bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl); 2598bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian ObjCInterfaceDecl *IDecl = C ? C->getClassInterface() 2599bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian : dyn_cast<ObjCInterfaceDecl>(CDecl); 2600f28385991fa724ac0bd6017d709f17b1838cfea3Fariborz Jahanian assert (IDecl && "CheckProtocolMethodDefs - IDecl is null"); 2601f28385991fa724ac0bd6017d709f17b1838cfea3Fariborz Jahanian 26027ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar ObjCInterfaceDecl *Super = IDecl->getSuperClass(); 26036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ObjCInterfaceDecl *NSIDecl = nullptr; 2604651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2605651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If this protocol is marked 'objc_protocol_requires_explicit_implementation' 2606651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // then we should check if any class in the super class hierarchy also 2607651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // conforms to this protocol, either directly or via protocol inheritance. 2608651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If so, we can skip checking this protocol completely because we 2609651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // know that a parent class already satisfies this protocol. 2610651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // 2611651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Note: we could generalize this logic for all protocols, and merely 2612651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // add the limit on looking at the super class chain for just 2613651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // specially marked protocols. This may be a good optimization. This 2614651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // change is restricted to 'objc_protocol_requires_explicit_implementation' 2615651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // protocols for now for controlled evaluation. 2616651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (PDecl->hasAttr<ObjCExplicitProtocolImplAttr>()) { 2617651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!ProtocolsExplictImpl) { 2618651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ProtocolsExplictImpl.reset(new ProtocolNameSet); 2619651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines findProtocolsWithExplicitImpls(Super, *ProtocolsExplictImpl); 2620651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 2621651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (ProtocolsExplictImpl->find(PDecl->getIdentifier()) != 2622651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ProtocolsExplictImpl->end()) 2623651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 2624651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2625651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If no super class conforms to the protocol, we should not search 2626651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // for methods in the super class to implicitly satisfy the protocol. 26276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Super = nullptr; 2628651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 2629651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2630651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (S.getLangOpts().ObjCRuntime.isNeXTFamily()) { 26311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // check to see if class implements forwardInvocation method and objects 26321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // of this class are derived from 'NSProxy' so that to forward requests 2633cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian // from one object to another. 26341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Under such conditions, which means that every method possible is 26351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // implemented in the class, we should not issue "Method definition not 2636cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian // found" warnings. 2637cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian // FIXME: Use a general GetUnarySelector method for this. 2638651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IdentifierInfo* II = &S.Context.Idents.get("forwardInvocation"); 2639651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Selector fISelector = S.Context.Selectors.getSelector(1, &II); 2640cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian if (InsMap.count(fISelector)) 2641cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian // Is IDecl derived from 'NSProxy'? If so, no instance methods 2642cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian // need be implemented in the implementation. 2643651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NSIDecl = IDecl->lookupInheritedClass(&S.Context.Idents.get("NSProxy")); 2644cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian } 26451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 264632b94bedc6a789e4091626e7433e73555cf9df00Fariborz Jahanian // If this is a forward protocol declaration, get its definition. 264732b94bedc6a789e4091626e7433e73555cf9df00Fariborz Jahanian if (!PDecl->isThisDeclarationADefinition() && 264832b94bedc6a789e4091626e7433e73555cf9df00Fariborz Jahanian PDecl->getDefinition()) 264932b94bedc6a789e4091626e7433e73555cf9df00Fariborz Jahanian PDecl = PDecl->getDefinition(); 265032b94bedc6a789e4091626e7433e73555cf9df00Fariborz Jahanian 26517ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar // If a method lookup fails locally we still need to look and see if 26527ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar // the method was implemented by a base class or an inherited 26537ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar // protocol. This lookup is slow, but occurs rarely in correct code 26547ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar // and otherwise would terminate in a warning. 26557ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar 26564d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // check unimplemented instance methods. 2657cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian if (!NSIDecl) 2658651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *method : PDecl->instance_methods()) { 26591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (method->getImplementationControl() != ObjCMethodDecl::Optional && 26601e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose !method->isPropertyAccessor() && 26611e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose !InsMap.count(method->getSelector()) && 2662651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (!Super || !Super->lookupMethod(method->getSelector(), 2663651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines true /* instance */, 2664651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines false /* shallowCategory */, 2665651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines true /* followsSuper */, 26666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr /* category */))) { 2667bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian // If a method is not implemented in the category implementation but 2668bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian // has been declared in its primary class, superclass, 2669bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian // or in one of their protocols, no need to issue the warning. 2670bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian // This is because method will be implemented in the primary class 2671bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian // or one of its super class implementation. 2672bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian 2673cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian // Ugly, but necessary. Method declared in protcol might have 2674cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian // have been synthesized due to a property declared in the class which 2675cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian // uses the protocol. 2676bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian if (ObjCMethodDecl *MethodInClass = 2677651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IDecl->lookupMethod(method->getSelector(), 2678651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines true /* instance */, 2679651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines true /* shallowCategoryLookup */, 2680651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines false /* followSuper */)) 26811e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose if (C || MethodInClass->isPropertyAccessor()) 2682bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian continue; 2683bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian unsigned DIAG = diag::warn_unimplemented_protocol_method; 2684c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!S.Diags.isIgnored(DIAG, ImpLoc)) { 2685651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, 2686651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PDecl); 26878822f7cda557ffa755c16b5c978dada23c37d6beFariborz Jahanian } 2688cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian } 2689cd1876207f5564beba74e4b2524b664bdba0ba9fFariborz Jahanian } 26904d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // check unimplemented class methods 2691651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *method : PDecl->class_methods()) { 26927ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar if (method->getImplementationControl() != ObjCMethodDecl::Optional && 26937ad1b1fa075e5cd4160d5b357b2a8d3f8a131984Daniel Dunbar !ClsMap.count(method->getSelector()) && 2694651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (!Super || !Super->lookupMethod(method->getSelector(), 2695651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines false /* class method */, 2696651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines false /* shallowCategoryLookup */, 2697651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines true /* followSuper */, 26986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr /* category */))) { 2699bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian // See above comment for instance method lookups. 2700651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (C && IDecl->lookupMethod(method->getSelector(), 2701651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines false /* class */, 2702651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines true /* shallowCategoryLookup */, 2703651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines false /* followSuper */)) 2704bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian continue; 2705651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2706521468391c0abbbfcf6b257442630c70314b8576Fariborz Jahanian unsigned DIAG = diag::warn_unimplemented_protocol_method; 2707c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!S.Diags.isIgnored(DIAG, ImpLoc)) { 2708651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, PDecl); 2709521468391c0abbbfcf6b257442630c70314b8576Fariborz Jahanian } 27108822f7cda557ffa755c16b5c978dada23c37d6beFariborz Jahanian } 271158dbdeb69c063f82d644504fc638120198f7fad2Steve Naroff } 2712780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner // Check on this protocols's referenced protocols, recursively. 2713651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *PI : PDecl->protocols()) 2714651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CheckProtocolMethodDefs(S, ImpLoc, PI, IncompleteImpl, InsMap, ClsMap, 2715651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CDecl, ProtocolsExplictImpl); 27164d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 27174d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 27181e159bc43cf6575a415dbe8deb7fc49611002ffeFariborz Jahanian/// MatchAllMethodDeclarations - Check methods declared in interface 2719b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian/// or protocol against those declared in their implementations. 2720b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian/// 2721811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramervoid Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap, 2722811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer const SelectorSet &ClsMap, 2723811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer SelectorSet &InsMapSeen, 2724811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer SelectorSet &ClsMapSeen, 2725b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian ObjCImplDecl* IMPDecl, 2726b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian ObjCContainerDecl* CDecl, 2727b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian bool &IncompleteImpl, 2728fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian bool ImmediateClass, 2729bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian bool WarnCategoryMethodImpl) { 2730b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // Check and see if instance methods in class interface have been 2731b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // implemented in the implementation class. If so, their types match. 2732651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *I : CDecl->instance_methods()) { 2733176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!InsMapSeen.insert(I->getSelector()).second) 27347dcff5b56bc470c456f70ecb124c3a9013c50953Benjamin Kramer continue; 2735651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!I->isPropertyAccessor() && 2736651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines !InsMap.count(I->getSelector())) { 2737b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian if (ImmediateClass) 2738651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines WarnUndefinedMethod(*this, IMPDecl->getLocation(), I, IncompleteImpl, 27398b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek diag::warn_undef_method_impl); 2740b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian continue; 2741ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 27421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCMethodDecl *ImpMethodDecl = 2743651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IMPDecl->getInstanceMethod(I->getSelector()); 2744651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(CDecl->getInstanceMethod(I->getSelector()) && 27452334f3aeda318f68e763379afa5ac7a91b90caa7Argyrios Kyrtzidis "Expected to find the method through lookup as well"); 2746b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // ImpMethodDecl may be null as in a @dynamic property. 2747fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (ImpMethodDecl) { 2748bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian if (!WarnCategoryMethodImpl) 2749651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines WarnConflictingTypedMethods(ImpMethodDecl, I, 2750fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian isa<ObjCProtocolDecl>(CDecl)); 2751651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else if (!I->isPropertyAccessor()) 2752651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines WarnExactTypedMethods(ImpMethodDecl, I, isa<ObjCProtocolDecl>(CDecl)); 2753fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian } 2754b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian } 2755b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian } 27561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2757b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // Check and see if class methods in class interface have been 2758b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // implemented in the implementation class. If so, their types match. 2759651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *I : CDecl->class_methods()) { 2760176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!ClsMapSeen.insert(I->getSelector()).second) 27617dcff5b56bc470c456f70ecb124c3a9013c50953Benjamin Kramer continue; 27624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!I->isPropertyAccessor() && 27634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar !ClsMap.count(I->getSelector())) { 2764b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian if (ImmediateClass) 2765651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines WarnUndefinedMethod(*this, IMPDecl->getLocation(), I, IncompleteImpl, 27668b43d2b0ea2d72b53a10f38903b176e58cb93b9cTed Kremenek diag::warn_undef_method_impl); 2767ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 276817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis ObjCMethodDecl *ImpMethodDecl = 2769651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IMPDecl->getClassMethod(I->getSelector()); 2770651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(CDecl->getClassMethod(I->getSelector()) && 27712334f3aeda318f68e763379afa5ac7a91b90caa7Argyrios Kyrtzidis "Expected to find the method through lookup as well"); 27724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // ImpMethodDecl may be null as in a @dynamic property. 27734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (ImpMethodDecl) { 27744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!WarnCategoryMethodImpl) 27754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar WarnConflictingTypedMethods(ImpMethodDecl, I, 27764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar isa<ObjCProtocolDecl>(CDecl)); 27774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar else if (!I->isPropertyAccessor()) 27784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar WarnExactTypedMethods(ImpMethodDecl, I, isa<ObjCProtocolDecl>(CDecl)); 27794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 2780b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian } 2781b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian } 2782f54e3aec8a12c3ce453b1012e686c4b88881564aFariborz Jahanian 278341594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl> (CDecl)) { 278441594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian // Also, check for methods declared in protocols inherited by 278541594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian // this protocol. 2786651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *PI : PD->protocols()) 278741594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, 2788651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IMPDecl, PI, IncompleteImpl, false, 278941594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian WarnCategoryMethodImpl); 279041594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian } 279141594c5489f783a8398c68da72abb87434cd5634Fariborz Jahanian 2792b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) { 27936a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian // when checking that methods in implementation match their declaration, 27946a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian // i.e. when WarnCategoryMethodImpl is false, check declarations in class 27956a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian // extension; as well as those in categories. 2796d329724745b49f894b768d47275b7c2713106e89Douglas Gregor if (!WarnCategoryMethodImpl) { 2797651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *Cat : I->visible_categories()) 27986a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, 279987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar IMPDecl, Cat, IncompleteImpl, 280087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ImmediateClass && Cat->IsClassExtension(), 28016a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian WarnCategoryMethodImpl); 2802d329724745b49f894b768d47275b7c2713106e89Douglas Gregor } else { 28036a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian // Also methods in class extensions need be looked at next. 2804651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *Ext : I->visible_extensions()) 28056a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, 2806651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IMPDecl, Ext, IncompleteImpl, false, 28076a6bb2810cc8478730002c950f9261f6cb5f6143Fariborz Jahanian WarnCategoryMethodImpl); 2808d329724745b49f894b768d47275b7c2713106e89Douglas Gregor } 2809d329724745b49f894b768d47275b7c2713106e89Douglas Gregor 2810b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // Check for any implementation of a methods declared in protocol. 2811651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *PI : I->all_referenced_protocols()) 28121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, 2813651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IMPDecl, PI, IncompleteImpl, false, 2814bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian WarnCategoryMethodImpl); 2815651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2816fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // FIXME. For now, we are not checking for extact match of methods 2817fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // in category implementation and its primary class's super class. 2818bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian if (!WarnCategoryMethodImpl && I->getSuperClass()) 2819b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, 28201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump IMPDecl, 2821b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian I->getSuperClass(), IncompleteImpl, false); 2822b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian } 2823b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian} 2824b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian 2825fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian/// CheckCategoryVsClassMethodMatches - Checks that methods implemented in 2826fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian/// category matches with those implemented in its primary class and 2827fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian/// warns each time an exact match is found. 2828fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanianvoid Sema::CheckCategoryVsClassMethodMatches( 2829fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian ObjCCategoryImplDecl *CatIMPDecl) { 2830fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // Get category's primary class. 2831fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian ObjCCategoryDecl *CatDecl = CatIMPDecl->getCategoryDecl(); 2832fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (!CatDecl) 2833fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return; 2834fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian ObjCInterfaceDecl *IDecl = CatDecl->getClassInterface(); 2835fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (!IDecl) 2836fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian return; 2837651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCInterfaceDecl *SuperIDecl = IDecl->getSuperClass(); 2838651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SelectorSet InsMap, ClsMap; 2839651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2840651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *I : CatIMPDecl->instance_methods()) { 2841651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Selector Sel = I->getSelector(); 2842651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // When checking for methods implemented in the category, skip over 2843651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // those declared in category class's super class. This is because 2844651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // the super class must implement the method. 2845651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (SuperIDecl && SuperIDecl->lookupMethod(Sel, true)) 2846651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 2847651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines InsMap.insert(Sel); 2848651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 2849651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2850651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *I : CatIMPDecl->class_methods()) { 2851651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Selector Sel = I->getSelector(); 2852651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (SuperIDecl && SuperIDecl->lookupMethod(Sel, false)) 2853651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 2854651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ClsMap.insert(Sel); 2855651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 2856651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (InsMap.empty() && ClsMap.empty()) 2857651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 2858651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2859811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer SelectorSet InsMapSeen, ClsMapSeen; 2860fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian bool IncompleteImpl = false; 2861fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, 2862fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian CatIMPDecl, IDecl, 2863bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian IncompleteImpl, false, 2864bb3d14e55d267bf5228699c7bf0c8ccdb71c8f46Fariborz Jahanian true /*WarnCategoryMethodImpl*/); 2865fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian} 2866eee3ef177a171c06f826c331e7a9e256d01eaeb0Fariborz Jahanian 286717cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanianvoid Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, 28681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCContainerDecl* CDecl, 2869cddc88800bbd1213ec70ae5153c6a7f2e380fd8dChris Lattner bool IncompleteImpl) { 2870811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer SelectorSet InsMap; 28714d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check and see if instance methods in class interface have been 28724d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // implemented in the implementation class. 2873651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *I : IMPDecl->instance_methods()) 2874651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines InsMap.insert(I->getSelector()); 28751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 287687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Add the selectors for getters/setters of @dynamic properties. 287787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar for (const auto *PImpl : IMPDecl->property_impls()) { 287887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // We only care about @dynamic implementations. 287987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (PImpl->getPropertyImplementation() != ObjCPropertyImplDecl::Dynamic) 288087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar continue; 288187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 288287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar const auto *P = PImpl->getPropertyDecl(); 288387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!P) continue; 288487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 288587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar InsMap.insert(P->getGetterName()); 288687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!P->getSetterName().isNull()) 288787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar InsMap.insert(P->getSetterName()); 288887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 288987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 289012bac2566e3136d4bd9d42e6aabe27e1038f7793Fariborz Jahanian // Check and see if properties declared in the interface have either 1) 289112bac2566e3136d4bd9d42e6aabe27e1038f7793Fariborz Jahanian // an implementation or 2) there is a @synthesize/@dynamic implementation 289212bac2566e3136d4bd9d42e6aabe27e1038f7793Fariborz Jahanian // of the property in the @implementation. 2893651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) { 2894651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool SynthesizeProperties = LangOpts.ObjCDefaultSynthProperties && 2895651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LangOpts.ObjCRuntime.isNonFragile() && 2896651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines !IDecl->isObjCRequiresPropertyDefs(); 2897651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, SynthesizeProperties); 2898651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 2899651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 290087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Diagnose null-resettable synthesized setters. 290187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar diagnoseNullResettableSynthesizedSetters(IMPDecl); 290287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 2903811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer SelectorSet ClsMap; 2904651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *I : IMPDecl->class_methods()) 2905651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ClsMap.insert(I->getSelector()); 29061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2907b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // Check for type conflict of methods declared in a class/protocol and 2908b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // its implementation; if any. 2909811bfcd823d51db6a06b3fd5a5943ff910b79d68Benjamin Kramer SelectorSet InsMapSeen, ClsMapSeen; 29101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, 29111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump IMPDecl, CDecl, 2912b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian IncompleteImpl, true); 291374133075f5024ce87e4c1eb644d77c20e1c521f4Fariborz Jahanian 2914fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // check all methods implemented in category against those declared 2915fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian // in its primary class. 2916fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian if (ObjCCategoryImplDecl *CatDecl = 2917fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian dyn_cast<ObjCCategoryImplDecl>(IMPDecl)) 2918fefe91e6017321aa7db431b94cb3615f6c97da7aFariborz Jahanian CheckCategoryVsClassMethodMatches(CatDecl); 29191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 29204d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check the protocol list for unimplemented methods in the @implementation 29214d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // class. 2922b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // Check and see if class methods in class interface have been 2923b33f3ad379f497c5fc6d0ada618745dd46d0e717Fariborz Jahanian // implemented in the implementation class. 29241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2925651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LazyProtocolNameSet ExplicitImplProtocols; 2926651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2927cddc88800bbd1213ec70ae5153c6a7f2e380fd8dChris Lattner if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) { 2928651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *PI : I->all_referenced_protocols()) 2929651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), PI, IncompleteImpl, 2930651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines InsMap, ClsMap, I, ExplicitImplProtocols); 2931cddc88800bbd1213ec70ae5153c6a7f2e380fd8dChris Lattner } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) { 2932b106fc635b1523952332131785b700453a936e49Fariborz Jahanian // For extended class, unimplemented methods in its protocols will 2933b106fc635b1523952332131785b700453a936e49Fariborz Jahanian // be reported in the primary class. 293425760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian if (!C->IsClassExtension()) { 2935651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *P : C->protocols()) 2936651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), P, 2937651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IncompleteImpl, InsMap, ClsMap, CDecl, 2938651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExplicitImplProtocols); 2939651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, 29400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines /*SynthesizeProperties=*/false); 29413ad230eb626d630877c17d6e81b167ec7476d84eFariborz Jahanian } 2942cddc88800bbd1213ec70ae5153c6a7f2e380fd8dChris Lattner } else 2943b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("invalid ObjCContainerDecl type."); 29444d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 29454d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 294695ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz JahanianSema::DeclGroupPtrTy 29474d3914836e85258e9ace7306999413e3c7ea6c11Chris LattnerSema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, 2948bdbde4db74ea9751e02081d720f415eae9718662Chris Lattner IdentifierInfo **IdentList, 2949c09cba67d0ad01e53e0fed07322e95dd281bcfd9Ted Kremenek SourceLocation *IdentLocs, 295087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ArrayRef<ObjCTypeParamList *> TypeParamLists, 2951bdbde4db74ea9751e02081d720f415eae9718662Chris Lattner unsigned NumElts) { 295295ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian SmallVector<Decl *, 8> DeclsInGroup; 29534d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner for (unsigned i = 0; i != NumElts; ++i) { 29544d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Check for another declaration kind with the same name. 2955f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *PrevDecl 2956c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor = LookupSingleName(TUScope, IdentList[i], IdentLocs[i], 2957c0b39640de335809ca7544f802751112619f30ccDouglas Gregor LookupOrdinaryName, ForRedeclaration); 2958a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) { 2959c7333881dcd00be87814d03c349dd96c815f2f05Steve Naroff // GCC apparently allows the following idiom: 2960c7333881dcd00be87814d03c349dd96c815f2f05Steve Naroff // 2961c7333881dcd00be87814d03c349dd96c815f2f05Steve Naroff // typedef NSObject < XCElementTogglerP > XCElementToggler; 2962c7333881dcd00be87814d03c349dd96c815f2f05Steve Naroff // @class XCElementToggler; 2963c7333881dcd00be87814d03c349dd96c815f2f05Steve Naroff // 2964e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian // Here we have chosen to ignore the forward class declaration 2965e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian // with a warning. Since this is the implied behavior. 2966162e1c1b487352434552147967c3dd296ebee2f7Richard Smith TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(PrevDecl); 2967c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall if (!TDD || !TDD->getUnderlyingType()->isObjCObjectType()) { 29683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(AtClassLoc, diag::err_redefinition_different_kind) << IdentList[i]; 29695f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(PrevDecl->getLocation(), diag::note_previous_definition); 2970c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall } else { 2971ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump // a forward class declaration matching a typedef name of a class refers 2972e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian // to the underlying class. Just ignore the forward class with a warning 29730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // as this will force the intended behavior which is to lookup the 29740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // typedef name. 2975e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian if (isa<ObjCObjectType>(TDD->getUnderlyingType())) { 29760e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Diag(AtClassLoc, diag::warn_forward_class_redefinition) 29770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines << IdentList[i]; 2978e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian Diag(PrevDecl->getLocation(), diag::note_previous_definition); 2979e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian continue; 2980e42670bb6885934f01a6f7ffce58add5b5b3822bFariborz Jahanian } 2981cae27c51f0da674cdd3b53b8b2f7ba08c44c54b0Fariborz Jahanian } 29824d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 29837723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor 29847723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor // Create a declaration to describe this forward declaration. 29850af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor ObjCInterfaceDecl *PrevIDecl 29860af550115df1f57f17a4f125ff0e8b34820c65d1Douglas Gregor = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl); 2987e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis 2988e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis IdentifierInfo *ClassName = IdentList[i]; 2989e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) { 2990e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // A previous decl with a different name is because of 2991e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // @compatibility_alias, for example: 2992e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // \code 2993e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // @class NewImage; 2994e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // @compatibility_alias OldImage NewImage; 2995e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // \endcode 2996e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // A lookup for 'OldImage' will return the 'NewImage' decl. 2997e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // 2998e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // In such a case use the real declaration name, instead of the alias one, 2999e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // otherwise we will break IdentifierResolver and redecls-chain invariants. 3000e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // FIXME: If necessary, add a bit to indicate that this ObjCInterfaceDecl 3001e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis // has been aliased. 3002e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis ClassName = PrevIDecl->getIdentifier(); 3003e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis } 3004e7e8fcacef233f35ad7e81083f7edd12497f6c40Argyrios Kyrtzidis 300587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If this forward declaration has type parameters, compare them with the 300687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // type parameters of the previous declaration. 300787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCTypeParamList *TypeParams = TypeParamLists[i]; 300887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (PrevIDecl && TypeParams) { 300987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (ObjCTypeParamList *PrevTypeParams = PrevIDecl->getTypeParamList()) { 301087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Check for consistency with the previous declaration. 301187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (checkTypeParamListConsistency( 301287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar *this, PrevTypeParams, TypeParams, 301387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar TypeParamListContext::ForwardDeclaration)) { 301487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar TypeParams = nullptr; 301587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 301687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) { 301787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // The @interface does not have type parameters. Complain. 301887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(IdentLocs[i], diag::err_objc_parameterized_forward_class) 301987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << ClassName 302087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << TypeParams->getSourceRange(); 302187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(Def->getLocation(), diag::note_defined_here) 302287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << ClassName; 302387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 302487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar TypeParams = nullptr; 302587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 302687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 302787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 30287723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor ObjCInterfaceDecl *IDecl 30297723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc, 303087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ClassName, TypeParams, PrevIDecl, 303187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar IdentLocs[i]); 30327723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor IDecl->setAtEndRange(IdentLocs[i]); 30337723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor 30347723fec9b45b7258c0eddf4cbfd0d335348f5edcDouglas Gregor PushOnScopeChains(IDecl, TUScope); 3035375bb1413c041055262c8a416f20d10474a5eda9Douglas Gregor CheckObjCDeclScope(IDecl); 3036375bb1413c041055262c8a416f20d10474a5eda9Douglas Gregor DeclsInGroup.push_back(IDecl); 30374d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 30384549d7ffc15bdd7ab860aa68db089d9f559b79e7Rafael Espindola 30394549d7ffc15bdd7ab860aa68db089d9f559b79e7Rafael Espindola return BuildDeclaratorGroup(DeclsInGroup, false); 30404d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 30414d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 30420f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCallstatic bool tryMatchRecordTypes(ASTContext &Context, 30430f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall Sema::MethodMatchStrategy strategy, 30440f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall const Type *left, const Type *right); 30450f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall 3046f85e193739c953358c865005855253af4f68a497John McCallstatic bool matchTypes(ASTContext &Context, Sema::MethodMatchStrategy strategy, 3047f85e193739c953358c865005855253af4f68a497John McCall QualType leftQT, QualType rightQT) { 3048f85e193739c953358c865005855253af4f68a497John McCall const Type *left = 3049f85e193739c953358c865005855253af4f68a497John McCall Context.getCanonicalType(leftQT).getUnqualifiedType().getTypePtr(); 3050f85e193739c953358c865005855253af4f68a497John McCall const Type *right = 3051f85e193739c953358c865005855253af4f68a497John McCall Context.getCanonicalType(rightQT).getUnqualifiedType().getTypePtr(); 3052f85e193739c953358c865005855253af4f68a497John McCall 3053f85e193739c953358c865005855253af4f68a497John McCall if (left == right) return true; 3054f85e193739c953358c865005855253af4f68a497John McCall 3055f85e193739c953358c865005855253af4f68a497John McCall // If we're doing a strict match, the types have to match exactly. 3056f85e193739c953358c865005855253af4f68a497John McCall if (strategy == Sema::MMS_strict) return false; 3057f85e193739c953358c865005855253af4f68a497John McCall 3058f85e193739c953358c865005855253af4f68a497John McCall if (left->isIncompleteType() || right->isIncompleteType()) return false; 3059f85e193739c953358c865005855253af4f68a497John McCall 3060f85e193739c953358c865005855253af4f68a497John McCall // Otherwise, use this absurdly complicated algorithm to try to 3061f85e193739c953358c865005855253af4f68a497John McCall // validate the basic, low-level compatibility of the two types. 3062f85e193739c953358c865005855253af4f68a497John McCall 3063f85e193739c953358c865005855253af4f68a497John McCall // As a minimum, require the sizes and alignments to match. 3064176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TypeInfo LeftTI = Context.getTypeInfo(left); 3065176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TypeInfo RightTI = Context.getTypeInfo(right); 3066176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (LeftTI.Width != RightTI.Width) 3067176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return false; 3068176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3069176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (LeftTI.Align != RightTI.Align) 3070f85e193739c953358c865005855253af4f68a497John McCall return false; 3071f85e193739c953358c865005855253af4f68a497John McCall 3072f85e193739c953358c865005855253af4f68a497John McCall // Consider all the kinds of non-dependent canonical types: 3073f85e193739c953358c865005855253af4f68a497John McCall // - functions and arrays aren't possible as return and parameter types 3074f85e193739c953358c865005855253af4f68a497John McCall 3075f85e193739c953358c865005855253af4f68a497John McCall // - vector types of equal size can be arbitrarily mixed 3076f85e193739c953358c865005855253af4f68a497John McCall if (isa<VectorType>(left)) return isa<VectorType>(right); 3077f85e193739c953358c865005855253af4f68a497John McCall if (isa<VectorType>(right)) return false; 3078f85e193739c953358c865005855253af4f68a497John McCall 3079f85e193739c953358c865005855253af4f68a497John McCall // - references should only match references of identical type 30800f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall // - structs, unions, and Objective-C objects must match more-or-less 30810f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall // exactly 3082f85e193739c953358c865005855253af4f68a497John McCall // - everything else should be a scalar 3083f85e193739c953358c865005855253af4f68a497John McCall if (!left->isScalarType() || !right->isScalarType()) 30840f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall return tryMatchRecordTypes(Context, strategy, left, right); 3085f85e193739c953358c865005855253af4f68a497John McCall 30861d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall // Make scalars agree in kind, except count bools as chars, and group 30871d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall // all non-member pointers together. 3088f85e193739c953358c865005855253af4f68a497John McCall Type::ScalarTypeKind leftSK = left->getScalarTypeKind(); 3089f85e193739c953358c865005855253af4f68a497John McCall Type::ScalarTypeKind rightSK = right->getScalarTypeKind(); 3090f85e193739c953358c865005855253af4f68a497John McCall if (leftSK == Type::STK_Bool) leftSK = Type::STK_Integral; 3091f85e193739c953358c865005855253af4f68a497John McCall if (rightSK == Type::STK_Bool) rightSK = Type::STK_Integral; 30921d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall if (leftSK == Type::STK_CPointer || leftSK == Type::STK_BlockPointer) 30931d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall leftSK = Type::STK_ObjCObjectPointer; 30941d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall if (rightSK == Type::STK_CPointer || rightSK == Type::STK_BlockPointer) 30951d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall rightSK = Type::STK_ObjCObjectPointer; 3096f85e193739c953358c865005855253af4f68a497John McCall 3097f85e193739c953358c865005855253af4f68a497John McCall // Note that data member pointers and function member pointers don't 3098f85e193739c953358c865005855253af4f68a497John McCall // intermix because of the size differences. 3099f85e193739c953358c865005855253af4f68a497John McCall 3100f85e193739c953358c865005855253af4f68a497John McCall return (leftSK == rightSK); 3101f85e193739c953358c865005855253af4f68a497John McCall} 31024d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 31030f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCallstatic bool tryMatchRecordTypes(ASTContext &Context, 31040f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall Sema::MethodMatchStrategy strategy, 31050f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall const Type *lt, const Type *rt) { 31060f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall assert(lt && rt && lt != rt); 31070f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall 31080f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall if (!isa<RecordType>(lt) || !isa<RecordType>(rt)) return false; 31090f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall RecordDecl *left = cast<RecordType>(lt)->getDecl(); 31100f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall RecordDecl *right = cast<RecordType>(rt)->getDecl(); 31110f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall 31120f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall // Require union-hood to match. 31130f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall if (left->isUnion() != right->isUnion()) return false; 31140f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall 31150f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall // Require an exact match if either is non-POD. 31160f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall if ((isa<CXXRecordDecl>(left) && !cast<CXXRecordDecl>(left)->isPOD()) || 31170f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall (isa<CXXRecordDecl>(right) && !cast<CXXRecordDecl>(right)->isPOD())) 31180f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall return false; 31190f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall 31200f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall // Require size and alignment to match. 3121176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TypeInfo LeftTI = Context.getTypeInfo(lt); 3122176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TypeInfo RightTI = Context.getTypeInfo(rt); 3123176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (LeftTI.Width != RightTI.Width) 3124176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return false; 3125176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3126176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (LeftTI.Align != RightTI.Align) 3127176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return false; 31280f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall 31290f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall // Require fields to match. 31300f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall RecordDecl::field_iterator li = left->field_begin(), le = left->field_end(); 31310f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall RecordDecl::field_iterator ri = right->field_begin(), re = right->field_end(); 31320f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall for (; li != le && ri != re; ++li, ++ri) { 31330f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall if (!matchTypes(Context, strategy, li->getType(), ri->getType())) 31340f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall return false; 31350f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall } 31360f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall return (li == le && ri == re); 31370f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall} 31380f4c4c4445b194db6a086ea91ec8e7af963a456cJohn McCall 31394d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// MatchTwoMethodDeclarations - Checks that two methods have matching type and 31404d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// returns true, or false, accordingly. 31414d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// TODO: Handle protocol list; such as id<p1,p2> in type comparisons 3142f85e193739c953358c865005855253af4f68a497John McCallbool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *left, 3143f85e193739c953358c865005855253af4f68a497John McCall const ObjCMethodDecl *right, 3144f85e193739c953358c865005855253af4f68a497John McCall MethodMatchStrategy strategy) { 3145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!matchTypes(Context, strategy, left->getReturnType(), 3146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines right->getReturnType())) 3147f85e193739c953358c865005855253af4f68a497John McCall return false; 31481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 31497666b03d499819214752ae392efe666ca856d0e7Douglas Gregor // If either is hidden, it is not considered to match. 31507666b03d499819214752ae392efe666ca856d0e7Douglas Gregor if (left->isHidden() || right->isHidden()) 31517666b03d499819214752ae392efe666ca856d0e7Douglas Gregor return false; 31527666b03d499819214752ae392efe666ca856d0e7Douglas Gregor 31534e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjCAutoRefCount && 3154f85e193739c953358c865005855253af4f68a497John McCall (left->hasAttr<NSReturnsRetainedAttr>() 3155f85e193739c953358c865005855253af4f68a497John McCall != right->hasAttr<NSReturnsRetainedAttr>() || 3156f85e193739c953358c865005855253af4f68a497John McCall left->hasAttr<NSConsumesSelfAttr>() 3157f85e193739c953358c865005855253af4f68a497John McCall != right->hasAttr<NSConsumesSelfAttr>())) 3158f85e193739c953358c865005855253af4f68a497John McCall return false; 31591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3160491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis ObjCMethodDecl::param_const_iterator 31610a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor li = left->param_begin(), le = left->param_end(), ri = right->param_begin(), 31620a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor re = right->param_end(); 3163f85e193739c953358c865005855253af4f68a497John McCall 31640a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor for (; li != le && ri != re; ++li, ++ri) { 3165f85e193739c953358c865005855253af4f68a497John McCall assert(ri != right->param_end() && "Param mismatch"); 3166491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis const ParmVarDecl *lparm = *li, *rparm = *ri; 3167f85e193739c953358c865005855253af4f68a497John McCall 3168f85e193739c953358c865005855253af4f68a497John McCall if (!matchTypes(Context, strategy, lparm->getType(), rparm->getType())) 3169f85e193739c953358c865005855253af4f68a497John McCall return false; 3170f85e193739c953358c865005855253af4f68a497John McCall 31714e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjCAutoRefCount && 3172f85e193739c953358c865005855253af4f68a497John McCall lparm->hasAttr<NSConsumedAttr>() != rparm->hasAttr<NSConsumedAttr>()) 3173f85e193739c953358c865005855253af4f68a497John McCall return false; 31744d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 31754d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner return true; 31764d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 31774d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 31784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic bool isMethodContextSameForKindofLookup(ObjCMethodDecl *Method, 31794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar ObjCMethodDecl *MethodInList) { 31804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto *MethodProtocol = dyn_cast<ObjCProtocolDecl>(Method->getDeclContext()); 31814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto *MethodInListProtocol = 31824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar dyn_cast<ObjCProtocolDecl>(MethodInList->getDeclContext()); 31834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // If this method belongs to a protocol but the method in list does not, or 31844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // vice versa, we say the context is not the same. 31854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if ((MethodProtocol && !MethodInListProtocol) || 31864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar (!MethodProtocol && MethodInListProtocol)) 31874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return false; 31884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 31894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (MethodProtocol && MethodInListProtocol) 31904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return true; 31914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 31924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar ObjCInterfaceDecl *MethodInterface = Method->getClassInterface(); 31934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar ObjCInterfaceDecl *MethodInListInterface = 31944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar MethodInList->getClassInterface(); 31954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return MethodInterface == MethodInListInterface; 31964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 31974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 31980e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid Sema::addMethodToGlobalList(ObjCMethodList *List, 31990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ObjCMethodDecl *Method) { 32002e3d8c0815acaf1bc5995ebe56cea07471e5c9c7Argyrios Kyrtzidis // Record at the head of the list whether there were 0, 1, or >= 2 methods 32012e3d8c0815acaf1bc5995ebe56cea07471e5c9c7Argyrios Kyrtzidis // inside categories. 32020e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (ObjCCategoryDecl *CD = 32030e2c34f92f00628d48968dfea096d36381f494cbStephen Hines dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) 3204ab3d509bc45218c278454962ff644bb13d18ce1aArgyrios Kyrtzidis if (!CD->IsClassExtension() && List->getBits() < 2) 32050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines List->setBits(List->getBits() + 1); 32062e3d8c0815acaf1bc5995ebe56cea07471e5c9c7Argyrios Kyrtzidis 320744fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // If the list is empty, make it a singleton list. 32080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (List->getMethod() == nullptr) { 32090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines List->setMethod(Method); 32106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines List->setNext(nullptr); 3211ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor return; 321244fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor } 32130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 321444fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // We've seen a method with this name, see if we have already seen this type 321544fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // signature. 321644fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor ObjCMethodList *Previous = List; 32174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar ObjCMethodList *ListWithSameDeclaration = nullptr; 32182e3d8c0815acaf1bc5995ebe56cea07471e5c9c7Argyrios Kyrtzidis for (; List; Previous = List, List = List->getNext()) { 3219fc46be997f8219e11900473c373b639525396064Douglas Gregor // If we are building a module, keep all of the methods. 32204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (getLangOpts().CompilingModule) 3221fc46be997f8219e11900473c373b639525396064Douglas Gregor continue; 3222fc46be997f8219e11900473c373b639525396064Douglas Gregor 32234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar bool SameDeclaration = MatchTwoMethodDeclarations(Method, 32244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar List->getMethod()); 32254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Looking for method with a type bound requires the correct context exists. 32264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // We need to insert a method into the list if the context is different. 32274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // If the method's declaration matches the list 32284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // a> the method belongs to a different context: we need to insert it, in 32294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // order to emit the availability message, we need to prioritize over 32304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // availability among the methods with the same declaration. 32314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // b> the method belongs to the same context: there is no need to insert a 32324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // new entry. 32334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // If the method's declaration does not match the list, we insert it to the 32344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // end. 32354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!SameDeclaration || 32364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar !isMethodContextSameForKindofLookup(Method, List->getMethod())) { 323758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar // Even if two method types do not match, we would like to say 323858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar // there is more than one declaration so unavailability/deprecated 323958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar // warning is not too noisy. 324058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar if (!Method->isDefined()) 324158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar List->setHasMoreThanOneDecl(true); 32424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 32434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // For methods with the same declaration, the one that is deprecated 32444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // should be put in the front for better diagnostics. 32454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Method->isDeprecated() && SameDeclaration && 32464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar !ListWithSameDeclaration && !List->getMethod()->isDeprecated()) 32474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar ListWithSameDeclaration = List; 32484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 32494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (Method->isUnavailable() && SameDeclaration && 32504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar !ListWithSameDeclaration && 32514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar List->getMethod()->getAvailability() < AR_Deprecated) 32524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar ListWithSameDeclaration = List; 325344fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor continue; 325458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar } 32550e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 32560e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ObjCMethodDecl *PrevObjCMethod = List->getMethod(); 325744fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor 325844fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // Propagate the 'defined' bit. 325944fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor if (Method->isDefined()) 326044fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor PrevObjCMethod->setDefined(true); 32610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines else { 32620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Objective-C doesn't allow an @interface for a class after its 32630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // @implementation. So if Method is not defined and there already is 32640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // an entry for this type signature, Method has to be for a different 32650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // class than PrevObjCMethod. 32660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines List->setHasMoreThanOneDecl(true); 32670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines } 32680e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 326944fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // If a method is deprecated, push it in the global pool. 327044fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // This is used for better diagnostics. 327144fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor if (Method->isDeprecated()) { 327244fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor if (!PrevObjCMethod->isDeprecated()) 32730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines List->setMethod(Method); 327444fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor } 32750e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // If the new method is unavailable, push it into global pool 327644fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // unless previous one is deprecated. 327744fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor if (Method->isUnavailable()) { 327844fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor if (PrevObjCMethod->getAvailability() < AR_Deprecated) 32790e2c34f92f00628d48968dfea096d36381f494cbStephen Hines List->setMethod(Method); 328044fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor } 32810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 3282ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor return; 328344fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor } 32840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 328544fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // We have a new signature for an existing method - add it. 328644fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor // This is extremely rare. Only 1% of Cocoa selectors are "overloaded". 32875ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>(); 32884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 32894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // We insert it right before ListWithSameDeclaration. 32904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (ListWithSameDeclaration) { 32914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto *List = new (Mem) ObjCMethodList(*ListWithSameDeclaration); 32924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // FIXME: should we clear the other bits in ListWithSameDeclaration? 32934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar ListWithSameDeclaration->setMethod(Method); 32944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar ListWithSameDeclaration->setNext(List); 32954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return; 32964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 32974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 32980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Previous->setNext(new (Mem) ObjCMethodList(Method)); 329944fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor} 330044fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor 3301db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl/// \brief Read the contents of the method pool for a given selector from 3302db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl/// external storage. 33035ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregorvoid Sema::ReadMethodPool(Selector Sel) { 3304f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor assert(ExternalSource && "We need an external AST source"); 33055ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor ExternalSource->ReadMethodPool(Sel); 3306f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor} 3307f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor 33084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarvoid Sema::updateOutOfDateSelector(Selector Sel) { 33094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!ExternalSource) 33104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return; 33114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar ExternalSource->updateOutOfDateSelector(Sel); 33124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 33134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3314ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregorvoid Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, 3315db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl bool instance) { 33169a0b6b4e2bf6a9ef41d32b4e83f2911981d2d44dArgyrios Kyrtzidis // Ignore methods of invalid containers. 33179a0b6b4e2bf6a9ef41d32b4e83f2911981d2d44dArgyrios Kyrtzidis if (cast<Decl>(Method->getDeclContext())->isInvalidDecl()) 3318ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor return; 33199a0b6b4e2bf6a9ef41d32b4e83f2911981d2d44dArgyrios Kyrtzidis 33200d266d623452f09d06973528217390d762a8f3faDouglas Gregor if (ExternalSource) 33210d266d623452f09d06973528217390d762a8f3faDouglas Gregor ReadMethodPool(Method->getSelector()); 33220d266d623452f09d06973528217390d762a8f3faDouglas Gregor 3323db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl GlobalMethodPool::iterator Pos = MethodPool.find(Method->getSelector()); 33240d266d623452f09d06973528217390d762a8f3faDouglas Gregor if (Pos == MethodPool.end()) 33250d266d623452f09d06973528217390d762a8f3faDouglas Gregor Pos = MethodPool.insert(std::make_pair(Method->getSelector(), 33260d266d623452f09d06973528217390d762a8f3faDouglas Gregor GlobalMethods())).first; 33270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 33283fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian Method->setDefined(impl); 332944fae525e792f09ecbe07c0a62cdbcb81e04306bDouglas Gregor 3330db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl ObjCMethodList &Entry = instance ? Pos->second.first : Pos->second.second; 3331ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor addMethodToGlobalList(&Entry, Method); 33324d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 33334d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 3334f85e193739c953358c865005855253af4f68a497John McCall/// Determines if this is an "acceptable" loose mismatch in the global 3335f85e193739c953358c865005855253af4f68a497John McCall/// method pool. This exists mostly as a hack to get around certain 3336f85e193739c953358c865005855253af4f68a497John McCall/// global mismatches which we can't afford to make warnings / errors. 3337f85e193739c953358c865005855253af4f68a497John McCall/// Really, what we want is a way to take a method out of the global 3338f85e193739c953358c865005855253af4f68a497John McCall/// method pool. 3339f85e193739c953358c865005855253af4f68a497John McCallstatic bool isAcceptableMethodMismatch(ObjCMethodDecl *chosen, 3340f85e193739c953358c865005855253af4f68a497John McCall ObjCMethodDecl *other) { 3341f85e193739c953358c865005855253af4f68a497John McCall if (!chosen->isInstanceMethod()) 3342f85e193739c953358c865005855253af4f68a497John McCall return false; 3343f85e193739c953358c865005855253af4f68a497John McCall 3344f85e193739c953358c865005855253af4f68a497John McCall Selector sel = chosen->getSelector(); 3345f85e193739c953358c865005855253af4f68a497John McCall if (!sel.isUnarySelector() || sel.getNameForSlot(0) != "length") 3346f85e193739c953358c865005855253af4f68a497John McCall return false; 3347f85e193739c953358c865005855253af4f68a497John McCall 3348f85e193739c953358c865005855253af4f68a497John McCall // Don't complain about mismatches for -length if the method we 3349f85e193739c953358c865005855253af4f68a497John McCall // chose has an integral result type. 3350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return (chosen->getReturnType()->isIntegerType()); 3351f85e193739c953358c865005855253af4f68a497John McCall} 3352f85e193739c953358c865005855253af4f68a497John McCall 33534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// Return true if the given method is wthin the type bound. 33544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic bool FilterMethodsByTypeBound(ObjCMethodDecl *Method, 33554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar const ObjCObjectType *TypeBound) { 33564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!TypeBound) 33574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return true; 33584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 33594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (TypeBound->isObjCId()) 33604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // FIXME: should we handle the case of bounding to id<A, B> differently? 33614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return true; 33624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 33634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto *BoundInterface = TypeBound->getInterface(); 33644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar assert(BoundInterface && "unexpected object type!"); 33654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 33664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Check if the Method belongs to a protocol. We should allow any method 33674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // defined in any protocol, because any subclass could adopt the protocol. 33684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar auto *MethodProtocol = dyn_cast<ObjCProtocolDecl>(Method->getDeclContext()); 33694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (MethodProtocol) { 33704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return true; 33714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 33724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 33734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // If the Method belongs to a class, check if it belongs to the class 33744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // hierarchy of the class bound. 33754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (ObjCInterfaceDecl *MethodInterface = Method->getClassInterface()) { 33764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // We allow methods declared within classes that are part of the hierarchy 33774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // of the class bound (superclass of, subclass of, or the same as the class 33784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // bound). 33794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return MethodInterface == BoundInterface || 33804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar MethodInterface->isSuperClassOf(BoundInterface) || 33814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar BoundInterface->isSuperClassOf(MethodInterface); 33824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 33834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar llvm_unreachable("unknow method context"); 33844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} 33854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 33864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// We first select the type of the method: Instance or Factory, then collect 33874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar/// all methods with that type. 33880e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesbool Sema::CollectMultipleMethodsInGlobalPool( 33894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Selector Sel, SmallVectorImpl<ObjCMethodDecl *> &Methods, 33904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar bool InstanceFirst, bool CheckTheOther, 33914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar const ObjCObjectType *TypeBound) { 3392176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (ExternalSource) 3393176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ReadMethodPool(Sel); 3394176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3395176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines GlobalMethodPool::iterator Pos = MethodPool.find(Sel); 3396176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (Pos == MethodPool.end()) 3397176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return false; 33984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3399176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Gather the non-hidden methods. 34004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar ObjCMethodList &MethList = InstanceFirst ? Pos->second.first : 34014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Pos->second.second; 3402176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines for (ObjCMethodList *M = &MethList; M; M = M->getNext()) 34034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (M->getMethod() && !M->getMethod()->isHidden()) { 34044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (FilterMethodsByTypeBound(M->getMethod(), TypeBound)) 34054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Methods.push_back(M->getMethod()); 34064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 34074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 34084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Return if we find any method with the desired kind. 34094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!Methods.empty()) 34104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return Methods.size() > 1; 34114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 34124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (!CheckTheOther) 34134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return false; 34144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 34154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Gather the other kind. 34164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar ObjCMethodList &MethList2 = InstanceFirst ? Pos->second.second : 34174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Pos->second.first; 34184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (ObjCMethodList *M = &MethList2; M; M = M->getNext()) 34194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (M->getMethod() && !M->getMethod()->isHidden()) { 34204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (FilterMethodsByTypeBound(M->getMethod(), TypeBound)) 34214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Methods.push_back(M->getMethod()); 34224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 34234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 34240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return Methods.size() > 1; 3425176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 3426176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 34274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarbool Sema::AreMultipleMethodsInGlobalPool( 34284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Selector Sel, ObjCMethodDecl *BestMethod, SourceRange R, 34294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar bool receiverIdOrClass, SmallVectorImpl<ObjCMethodDecl *> &Methods) { 34304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar // Diagnose finding more than one method in global pool. 34314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar SmallVector<ObjCMethodDecl *, 4> FilteredMethods; 34324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar FilteredMethods.push_back(BestMethod); 34334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 34344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (auto *M : Methods) 34354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (M != BestMethod && !M->hasAttr<UnavailableAttr>()) 34364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar FilteredMethods.push_back(M); 34374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 34384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (FilteredMethods.size() > 1) 34394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar DiagnoseMultipleMethodInGlobalPool(FilteredMethods, Sel, R, 34404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar receiverIdOrClass); 34414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 3442176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines GlobalMethodPool::iterator Pos = MethodPool.find(Sel); 34430e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Test for no method in the pool which should not trigger any warning by 34440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // caller. 3445176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (Pos == MethodPool.end()) 3446176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return true; 344758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar ObjCMethodList &MethList = 344858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar BestMethod->isInstanceMethod() ? Pos->second.first : Pos->second.second; 34490e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return MethList.hasMoreThanOneDecl(); 3450176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 3451176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3452db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian RedlObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R, 34536b308f6dc7d8f1581c52095f435c0e1284b111d8Fariborz Jahanian bool receiverIdOrClass, 345458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar bool instance) { 34550d266d623452f09d06973528217390d762a8f3faDouglas Gregor if (ExternalSource) 34560d266d623452f09d06973528217390d762a8f3faDouglas Gregor ReadMethodPool(Sel); 34570d266d623452f09d06973528217390d762a8f3faDouglas Gregor 3458db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl GlobalMethodPool::iterator Pos = MethodPool.find(Sel); 34590d266d623452f09d06973528217390d762a8f3faDouglas Gregor if (Pos == MethodPool.end()) 34606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 3461f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor 3462f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor // Gather the non-hidden methods. 3463db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second; 3464e7205c0e2472dd66238f4c6b6db1b7cc2957b42aRobert Wilhelm SmallVector<ObjCMethodDecl *, 4> Methods; 34652e3d8c0815acaf1bc5995ebe56cea07471e5c9c7Argyrios Kyrtzidis for (ObjCMethodList *M = &MethList; M; M = M->getNext()) { 346658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar if (M->getMethod() && !M->getMethod()->isHidden()) 346758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar return M->getMethod(); 3468f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor } 346958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar return nullptr; 347058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar} 34711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 347258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainarvoid Sema::DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl*> &Methods, 347358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar Selector Sel, SourceRange R, 347458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar bool receiverIdOrClass) { 3475f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor // We found multiple methods, so we may have to complain. 3476f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor bool issueDiagnostic = false, issueError = false; 3477b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar 3478f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor // We support a warning which complains about *any* difference in 3479f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor // method signature. 3480f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor bool strictSelectorMatch = 348158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar receiverIdOrClass && 348258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar !Diags.isIgnored(diag::warn_strict_multiple_method_decl, R.getBegin()); 3483f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor if (strictSelectorMatch) { 3484f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor for (unsigned I = 1, N = Methods.size(); I != N; ++I) { 3485f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_strict)) { 3486f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor issueDiagnostic = true; 3487f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor break; 34886b308f6dc7d8f1581c52095f435c0e1284b111d8Fariborz Jahanian } 3489f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor } 3490f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor } 3491b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar 3492f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor // If we didn't see any strict differences, we won't see any loose 3493f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor // differences. In ARC, however, we also need to check for loose 3494f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor // mismatches, because most of them are errors. 3495f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor if (!strictSelectorMatch || 3496f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor (issueDiagnostic && getLangOpts().ObjCAutoRefCount)) 3497f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor for (unsigned I = 1, N = Methods.size(); I != N; ++I) { 3498f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor // This checks if the methods differ in type mismatch. 3499f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_loose) && 3500f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor !isAcceptableMethodMismatch(Methods[0], Methods[I])) { 3501f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor issueDiagnostic = true; 3502f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor if (getLangOpts().ObjCAutoRefCount) 3503f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor issueError = true; 3504f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor break; 3505f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor } 35064d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 350758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar 3508f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor if (issueDiagnostic) { 3509f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor if (issueError) 3510f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor Diag(R.getBegin(), diag::err_arc_multiple_method_decl) << Sel << R; 3511f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor else if (strictSelectorMatch) 3512f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor Diag(R.getBegin(), diag::warn_strict_multiple_method_decl) << Sel << R; 3513f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor else 3514f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R; 351558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar 3516f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor Diag(Methods[0]->getLocStart(), 3517f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor issueError ? diag::note_possibility : diag::note_using) 351858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar << Methods[0]->getSourceRange(); 3519f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor for (unsigned I = 1, N = Methods.size(); I != N; ++I) { 3520f0e00046711280d494f3ef2d85ae67a442b97406Douglas Gregor Diag(Methods[I]->getLocStart(), diag::note_also_found) 352158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar << Methods[I]->getSourceRange(); 352258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar } 3523f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor } 3524f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor} 3525f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor 35263fe104154dd2e8ffb351142d74f308938b5c99bfFariborz JahanianObjCMethodDecl *Sema::LookupImplementedMethodInGlobalPool(Selector Sel) { 3527db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl GlobalMethodPool::iterator Pos = MethodPool.find(Sel); 3528db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl if (Pos == MethodPool.end()) 35296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 3530db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl 3531db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl GlobalMethods &Methods = Pos->second; 3532651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const ObjCMethodList *Method = &Methods.first; Method; 3533651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Method = Method->getNext()) 35340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (Method->getMethod() && 35350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines (Method->getMethod()->isDefined() || 35360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Method->getMethod()->isPropertyAccessor())) 35370e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return Method->getMethod(); 3538651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3539651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const ObjCMethodList *Method = &Methods.second; Method; 3540651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Method = Method->getNext()) 35410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (Method->getMethod() && 35420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines (Method->getMethod()->isDefined() || 35430e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Method->getMethod()->isPropertyAccessor())) 35440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines return Method->getMethod(); 35456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 35463fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian} 35473fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian 3548f98c688968777214bfff7a6cc9bbd4ff78e9c1d3Fariborz Jahanianstatic void 35499464a08a743295d6aefaca1a751b5b4d371cf99cFariborz JahanianHelperSelectorsForTypoCorrection( 35509464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian SmallVectorImpl<const ObjCMethodDecl *> &BestMethod, 35519464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian StringRef Typo, const ObjCMethodDecl * Method) { 35529464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian const unsigned MaxEditDistance = 1; 35539464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian unsigned BestEditDistance = MaxEditDistance + 1; 35544fe9644dc3533e4517f980645957c6fc9408c6f6Richard Trieu std::string MethodName = Method->getSelector().getAsString(); 35559464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian 35569464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian unsigned MinPossibleEditDistance = abs((int)MethodName.size() - (int)Typo.size()); 35579464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian if (MinPossibleEditDistance > 0 && 35589464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian Typo.size() / MinPossibleEditDistance < 1) 35599464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian return; 35609464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian unsigned EditDistance = Typo.edit_distance(MethodName, true, MaxEditDistance); 35619464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian if (EditDistance > MaxEditDistance) 35629464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian return; 35639464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian if (EditDistance == BestEditDistance) 35649464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian BestMethod.push_back(Method); 35659464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian else if (EditDistance < BestEditDistance) { 35669464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian BestMethod.clear(); 35679464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian BestMethod.push_back(Method); 35689464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian } 35699464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian} 35709464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian 3571d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanianstatic bool HelperIsMethodInObjCType(Sema &S, Selector Sel, 3572d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian QualType ObjectType) { 3573d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian if (ObjectType.isNull()) 3574d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian return true; 3575d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian if (S.LookupMethodInObjectType(Sel, ObjectType, true/*Instance method*/)) 3576d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian return true; 35776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return S.LookupMethodInObjectType(Sel, ObjectType, false/*Class method*/) != 35786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr; 3579d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian} 3580d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian 35819464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanianconst ObjCMethodDecl * 3582d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz JahanianSema::SelectorsForTypoCorrection(Selector Sel, 3583d395e34ae7aeeeaf9a37a12bc0f6de87158c95c3Fariborz Jahanian QualType ObjectType) { 35849464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian unsigned NumArgs = Sel.getNumArgs(); 35859464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian SmallVector<const ObjCMethodDecl *, 8> Methods; 3586419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian bool ObjectIsId = true, ObjectIsClass = true; 3587419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian if (ObjectType.isNull()) 3588419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian ObjectIsId = ObjectIsClass = false; 3589419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian else if (!ObjectType->isObjCObjectPointerType()) 35906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 3591419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian else if (const ObjCObjectPointerType *ObjCPtr = 3592419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian ObjectType->getAsObjCInterfacePointerType()) { 3593419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian ObjectType = QualType(ObjCPtr->getInterfaceType(), 0); 3594419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian ObjectIsId = ObjectIsClass = false; 3595419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian } 3596419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian else if (ObjectType->isObjCIdType() || ObjectType->isObjCQualifiedIdType()) 3597419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian ObjectIsClass = false; 3598419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian else if (ObjectType->isObjCClassType() || ObjectType->isObjCQualifiedClassType()) 3599419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian ObjectIsId = false; 3600419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian else 36016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 36026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 36039464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian for (GlobalMethodPool::iterator b = MethodPool.begin(), 36049464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian e = MethodPool.end(); b != e; b++) { 36059464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian // instance methods 36069464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian for (ObjCMethodList *M = &b->second.first; M; M=M->getNext()) 36070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (M->getMethod() && 36080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines (M->getMethod()->getSelector().getNumArgs() == NumArgs) && 36090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines (M->getMethod()->getSelector() != Sel)) { 3610419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian if (ObjectIsId) 36110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Methods.push_back(M->getMethod()); 3612419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian else if (!ObjectIsClass && 36130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines HelperIsMethodInObjCType(*this, M->getMethod()->getSelector(), 36140e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ObjectType)) 36150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Methods.push_back(M->getMethod()); 3616419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian } 36179464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian // class methods 36189464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian for (ObjCMethodList *M = &b->second.second; M; M=M->getNext()) 36190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (M->getMethod() && 36200e2c34f92f00628d48968dfea096d36381f494cbStephen Hines (M->getMethod()->getSelector().getNumArgs() == NumArgs) && 36210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines (M->getMethod()->getSelector() != Sel)) { 3622419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian if (ObjectIsClass) 36230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Methods.push_back(M->getMethod()); 3624419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian else if (!ObjectIsId && 36250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines HelperIsMethodInObjCType(*this, M->getMethod()->getSelector(), 36260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ObjectType)) 36270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines Methods.push_back(M->getMethod()); 3628419245e0719e1785e4eb3954ddaee122e921c738Fariborz Jahanian } 36299464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian } 36309464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian 36319464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian SmallVector<const ObjCMethodDecl *, 8> SelectedMethods; 36329464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian for (unsigned i = 0, e = Methods.size(); i < e; i++) { 36339464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian HelperSelectorsForTypoCorrection(SelectedMethods, 36349464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian Sel.getAsString(), Methods[i]); 36359464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian } 36366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return (SelectedMethods.size() == 1) ? SelectedMethods[0] : nullptr; 36379464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian} 36389464a08a743295d6aefaca1a751b5b4d371cf99cFariborz Jahanian 3639f98c688968777214bfff7a6cc9bbd4ff78e9c1d3Fariborz Jahanian/// DiagnoseDuplicateIvars - 3640f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian/// Check for duplicate ivars in the entire class at the start of 36411dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// \@implementation. This becomes necesssary because class extension can 3642f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian/// add ivars to a class in random order which will not be known until 36431dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// class's \@implementation is seen. 3644f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanianvoid Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, 3645f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian ObjCInterfaceDecl *SID) { 3646651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *Ivar : ID->ivars()) { 3647f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian if (Ivar->isInvalidDecl()) 3648f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian continue; 3649f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian if (IdentifierInfo *II = Ivar->getIdentifier()) { 3650f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian ObjCIvarDecl* prevIvar = SID->lookupInstanceVariable(II); 3651f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian if (prevIvar) { 3652f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian Diag(Ivar->getLocation(), diag::err_duplicate_member) << II; 3653f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian Diag(prevIvar->getLocation(), diag::note_previous_declaration); 3654f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian Ivar->setInvalidDecl(); 3655f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian } 3656f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian } 3657f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian } 3658f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian} 3659f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian 366087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// Diagnose attempts to define ARC-__weak ivars when __weak is disabled. 366187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstatic void DiagnoseWeakIvars(Sema &S, ObjCImplementationDecl *ID) { 366287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (S.getLangOpts().ObjCWeak) return; 366387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 366487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar for (auto ivar = ID->getClassInterface()->all_declared_ivar_begin(); 366587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ivar; ivar = ivar->getNextIvar()) { 366687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (ivar->isInvalidDecl()) continue; 366787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (ivar->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { 366887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (S.getLangOpts().ObjCWeakRuntime) { 366987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Diag(ivar->getLocation(), diag::err_arc_weak_disabled); 367087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else { 367187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Diag(ivar->getLocation(), diag::err_arc_weak_no_runtime); 367287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 367387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 367487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 367587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} 367687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 3677d64251fd56577dd5c78903454632361e094c6dc1Erik VerbruggenSema::ObjCContainerKind Sema::getObjCContainerKind() const { 3678d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen switch (CurContext->getDeclKind()) { 3679d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen case Decl::ObjCInterface: 3680d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen return Sema::OCK_Interface; 3681d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen case Decl::ObjCProtocol: 3682d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen return Sema::OCK_Protocol; 3683d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen case Decl::ObjCCategory: 368458878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar if (cast<ObjCCategoryDecl>(CurContext)->IsClassExtension()) 3685d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen return Sema::OCK_ClassExtension; 368658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar return Sema::OCK_Category; 3687d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen case Decl::ObjCImplementation: 3688d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen return Sema::OCK_Implementation; 3689d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen case Decl::ObjCCategoryImpl: 3690d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen return Sema::OCK_CategoryImplementation; 3691d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen 3692d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen default: 3693d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen return Sema::OCK_None; 3694d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen } 3695d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen} 3696d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen 3697a3c6246950f23d7d4cd748badaf8f05d7bc3f14aFariborz Jahanian// Note: For class/category implementations, allMethods is always null. 36980111e4da0133c7fb4815e5c60524d2aaddfbccf0Robert WilhelmDecl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods, 369980f8aca7aeac5be1c9c33813c2afcab6538199aaFariborz Jahanian ArrayRef<DeclGroupPtrTy> allTUVars) { 3700d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen if (getObjCContainerKind() == Sema::OCK_None) 37016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 3702d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen 3703d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen assert(AtEnd.isValid() && "Invalid location for '@end'"); 3704a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian 3705a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext); 3706a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian Decl *ClassDecl = cast<Decl>(OCD); 370763e963cdffca9530f920dbab58b9b4eecb2a582cFariborz Jahanian 37081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool isInterfaceDeclKind = 3709f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl) 3710f8d17a59167d9c2026506ed8813ea434d93b662aChris Lattner || isa<ObjCProtocolDecl>(ClassDecl); 3711a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl); 371209c4719788a5cea09897525e528fa00420f1677bSteve Naroff 37130701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff // FIXME: Remove these and use the ObjCContainerDecl/DeclContext. 37140701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap; 37150701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap; 37160701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff 3717a3c6246950f23d7d4cd748badaf8f05d7bc3f14aFariborz Jahanian for (unsigned i = 0, e = allMethods.size(); i != e; i++ ) { 3718a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek ObjCMethodDecl *Method = 3719d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall cast_or_null<ObjCMethodDecl>(allMethods[i]); 37204d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 37214d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (!Method) continue; // Already issued a diagnostic. 3722f8d49f64ef6ab7e632717a31631fc289aab69428Douglas Gregor if (Method->isInstanceMethod()) { 37234d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner /// Check for instance method of the same name with incompatible types 3724a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek const ObjCMethodDecl *&PrevMethod = InsMap[Method->getSelector()]; 37251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod) 37264d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner : false; 37271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if ((isInterfaceDeclKind && PrevMethod && !match) 372882b4e768d38c12ceba7db23a96e8d845e00fdeb7Eli Friedman || (checkIdenticalMethods && match)) { 37295f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(Method->getLocation(), diag::err_duplicate_method_decl) 3730077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner << Method->getDeclName(); 37315f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(PrevMethod->getLocation(), diag::note_previous_declaration); 3732bdb2d5056fd675c27307b34efd371bbba6839e92Douglas Gregor Method->setInvalidDecl(); 37334d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } else { 37347209646add692c50503435bcffb13187a3349552Fariborz Jahanian if (PrevMethod) { 37353a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis Method->setAsRedeclaration(PrevMethod); 37367209646add692c50503435bcffb13187a3349552Fariborz Jahanian if (!Context.getSourceManager().isInSystemHeader( 37377209646add692c50503435bcffb13187a3349552Fariborz Jahanian Method->getLocation())) 37387209646add692c50503435bcffb13187a3349552Fariborz Jahanian Diag(Method->getLocation(), diag::warn_duplicate_method_decl) 37397209646add692c50503435bcffb13187a3349552Fariborz Jahanian << Method->getDeclName(); 37407209646add692c50503435bcffb13187a3349552Fariborz Jahanian Diag(PrevMethod->getLocation(), diag::note_previous_declaration); 37417209646add692c50503435bcffb13187a3349552Fariborz Jahanian } 37424d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner InsMap[Method->getSelector()] = Method; 37434d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner /// The following allows us to typecheck messages to "id". 3744ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor AddInstanceMethodToGlobalPool(Method); 37454d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 3746ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 37474d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner /// Check for class method of the same name with incompatible types 3748a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek const ObjCMethodDecl *&PrevMethod = ClsMap[Method->getSelector()]; 37491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod) 37504d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner : false; 37511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if ((isInterfaceDeclKind && PrevMethod && !match) 375282b4e768d38c12ceba7db23a96e8d845e00fdeb7Eli Friedman || (checkIdenticalMethods && match)) { 37535f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(Method->getLocation(), diag::err_duplicate_method_decl) 3754077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner << Method->getDeclName(); 37555f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(PrevMethod->getLocation(), diag::note_previous_declaration); 3756bdb2d5056fd675c27307b34efd371bbba6839e92Douglas Gregor Method->setInvalidDecl(); 37574d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } else { 37587209646add692c50503435bcffb13187a3349552Fariborz Jahanian if (PrevMethod) { 37593a919e7110407ae7609bb6edc57aac16a5990661Argyrios Kyrtzidis Method->setAsRedeclaration(PrevMethod); 37607209646add692c50503435bcffb13187a3349552Fariborz Jahanian if (!Context.getSourceManager().isInSystemHeader( 37617209646add692c50503435bcffb13187a3349552Fariborz Jahanian Method->getLocation())) 37627209646add692c50503435bcffb13187a3349552Fariborz Jahanian Diag(Method->getLocation(), diag::warn_duplicate_method_decl) 37637209646add692c50503435bcffb13187a3349552Fariborz Jahanian << Method->getDeclName(); 37647209646add692c50503435bcffb13187a3349552Fariborz Jahanian Diag(PrevMethod->getLocation(), diag::note_previous_declaration); 37657209646add692c50503435bcffb13187a3349552Fariborz Jahanian } 37664d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner ClsMap[Method->getSelector()] = Method; 3767ff310c763eeb41a7aaa3b928cd0bc0a6e493d5ddDouglas Gregor AddFactoryMethodToGlobalPool(Method); 37684d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 37694d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 37704d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 3771b892d7010f9c2c61e2f3a2686546cbfbffbedef3Douglas Gregor if (isa<ObjCInterfaceDecl>(ClassDecl)) { 3772b892d7010f9c2c61e2f3a2686546cbfbffbedef3Douglas Gregor // Nothing to do here. 377309c4719788a5cea09897525e528fa00420f1677bSteve Naroff } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) { 377477e14bd3a714be42dbe1ab90a37b5832740b6df2Fariborz Jahanian // Categories are used to extend the class by declaring new methods. 37751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // By the same token, they are also used to add new properties. No 377677e14bd3a714be42dbe1ab90a37b5832740b6df2Fariborz Jahanian // need to compare the added property to those in the class. 3777b20ef3e3fbe0fabe213dc0149011e9f0d751a3a4Daniel Dunbar 377888f5e9be350f4b107f8665183a6d441874e0fcc7Fariborz Jahanian if (C->IsClassExtension()) { 377988f5e9be350f4b107f8665183a6d441874e0fcc7Fariborz Jahanian ObjCInterfaceDecl *CCPrimary = C->getClassInterface(); 378088f5e9be350f4b107f8665183a6d441874e0fcc7Fariborz Jahanian DiagnoseClassExtensionDupMethods(C, CCPrimary); 378188f5e9be350f4b107f8665183a6d441874e0fcc7Fariborz Jahanian } 37824d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 378309c4719788a5cea09897525e528fa00420f1677bSteve Naroff if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(ClassDecl)) { 378425760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian if (CDecl->getIdentifier()) 378525760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian // ProcessPropertyDecl is responsible for diagnosing conflicts with any 378625760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian // user-defined setter/getter. It also synthesizes setter/getter methods 378725760611365be23556b32332f8a66ae21ea93ecfFariborz Jahanian // and adds them to the DeclContext and global method pools. 3788651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *I : CDecl->properties()) 378987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ProcessPropertyDecl(I); 3790782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek CDecl->setAtEndRange(AtEnd); 379109c4719788a5cea09897525e528fa00420f1677bSteve Naroff } 379209c4719788a5cea09897525e528fa00420f1677bSteve Naroff if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) { 3793782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek IC->setAtEndRange(AtEnd); 37947ca8b0694840385d707689eba9ad965e7b28c8cbFariborz Jahanian if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) { 3795c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian // Any property declared in a class extension might have user 3796c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian // declared setter or getter in current class extension or one 3797c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian // of the other class extensions. Mark them as synthesized as 3798c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian // property will be synthesized when property with same name is 3799c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian // seen in the @implementation. 3800651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *Ext : IDecl->visible_extensions()) { 38014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar for (const auto *Property : Ext->instance_properties()) { 3802c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian // Skip over properties declared @dynamic 3803c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian if (const ObjCPropertyImplDecl *PIDecl 38044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar = IC->FindPropertyImplDecl(Property->getIdentifier(), 38054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Property->getQueryKind())) 3806c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian if (PIDecl->getPropertyImplementation() 3807c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian == ObjCPropertyImplDecl::Dynamic) 3808c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian continue; 3809d329724745b49f894b768d47275b7c2713106e89Douglas Gregor 3810651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *Ext : IDecl->visible_extensions()) { 3811d329724745b49f894b768d47275b7c2713106e89Douglas Gregor if (ObjCMethodDecl *GetterMethod 3812d329724745b49f894b768d47275b7c2713106e89Douglas Gregor = Ext->getInstanceMethod(Property->getGetterName())) 38131e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose GetterMethod->setPropertyAccessor(true); 3814c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian if (!Property->isReadOnly()) 3815d329724745b49f894b768d47275b7c2713106e89Douglas Gregor if (ObjCMethodDecl *SetterMethod 3816d329724745b49f894b768d47275b7c2713106e89Douglas Gregor = Ext->getInstanceMethod(Property->getSetterName())) 38171e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose SetterMethod->setPropertyAccessor(true); 3818d329724745b49f894b768d47275b7c2713106e89Douglas Gregor } 3819c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian } 3820c78f684c8e300414956bc1566957a17a48da2fc8Fariborz Jahanian } 382117cb326cb62a59f53d92236394af40eaae4eddbdFariborz Jahanian ImplMethodsVsClassMethods(S, IC, IDecl); 38227ca8b0694840385d707689eba9ad965e7b28c8cbFariborz Jahanian AtomicPropertySetterGetterRules(IC, IDecl); 3823f85e193739c953358c865005855253af4f68a497John McCall DiagnoseOwningPropertyGetterSynthesis(IC); 3824651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DiagnoseUnusedBackingIvarInAccessor(S, IC); 3825651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (IDecl->hasDesignatedInitializers()) 3826651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DiagnoseMissingDesignatedInitOverrides(IC, IDecl); 382787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar DiagnoseWeakIvars(*this, IC); 3828651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3829b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard bool HasRootClassAttr = IDecl->hasAttr<ObjCRootClassAttr>(); 38306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (IDecl->getSuperClass() == nullptr) { 3831b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard // This class has no superclass, so check that it has been marked with 3832b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard // __attribute((objc_root_class)). 3833b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard if (!HasRootClassAttr) { 3834b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard SourceLocation DeclLoc(IDecl->getLocation()); 38356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceLocation SuperClassLoc(getLocForEndOfToken(DeclLoc)); 3836b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard Diag(DeclLoc, diag::warn_objc_root_class_missing) 3837b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard << IDecl->getIdentifier(); 3838b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard // See if NSObject is in the current scope, and if it is, suggest 3839b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard // adding " : NSObject " to the class declaration. 3840b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard NamedDecl *IF = LookupSingleName(TUScope, 3841b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject), 3842b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard DeclLoc, LookupOrdinaryName); 3843b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard ObjCInterfaceDecl *NSObjectDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF); 3844b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard if (NSObjectDecl && NSObjectDecl->getDefinition()) { 3845b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard Diag(SuperClassLoc, diag::note_objc_needs_superclass) 3846b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard << FixItHint::CreateInsertion(SuperClassLoc, " : NSObject "); 3847b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } else { 3848b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard Diag(SuperClassLoc, diag::note_objc_needs_superclass); 3849b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } 3850b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } 3851b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } else if (HasRootClassAttr) { 3852b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard // Complain that only root classes may have this attribute. 3853b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard Diag(IDecl->getLocation(), diag::err_objc_root_class_subclass); 3854b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } 3855b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard 3856260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (LangOpts.ObjCRuntime.isNonFragile()) { 3857f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian while (IDecl->getSuperClass()) { 3858f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass()); 3859f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian IDecl = IDecl->getSuperClass(); 3860f914b9782a6091a7c7dfd41b0a273ee724351b84Fariborz Jahanian } 3861b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } 38627ca8b0694840385d707689eba9ad965e7b28c8cbFariborz Jahanian } 3863e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian SetIvarInitializers(IC); 38641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } else if (ObjCCategoryImplDecl* CatImplClass = 386509c4719788a5cea09897525e528fa00420f1677bSteve Naroff dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) { 3866782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek CatImplClass->setAtEndRange(AtEnd); 38671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 38684d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // Find category interface decl and then check that all methods declared 3869b20ef3e3fbe0fabe213dc0149011e9f0d751a3a4Daniel Dunbar // in this interface are implemented in the category @implementation. 387097a588715d6c896158106d6ca732196d3fee857bChris Lattner if (ObjCInterfaceDecl* IDecl = CatImplClass->getClassInterface()) { 3871d329724745b49f894b768d47275b7c2713106e89Douglas Gregor if (ObjCCategoryDecl *Cat 3872d329724745b49f894b768d47275b7c2713106e89Douglas Gregor = IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier())) { 3873d329724745b49f894b768d47275b7c2713106e89Douglas Gregor ImplMethodsVsClassMethods(S, CatImplClass, Cat); 38744d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 38754d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 38764d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 3877682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner if (isInterfaceDeclKind) { 3878682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner // Reject invalid vardecls. 3879a3c6246950f23d7d4cd748badaf8f05d7bc3f14aFariborz Jahanian for (unsigned i = 0, e = allTUVars.size(); i != e; i++) { 388018062394db459158942ab491a88b9d52a5c0ab0dSerge Pavlov DeclGroupRef DG = allTUVars[i].get(); 3881682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) 3882682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner if (VarDecl *VDecl = dyn_cast<VarDecl>(*I)) { 38835466c7b0ca8ce662e2c0bc295cecba2b78d6957dDaniel Dunbar if (!VDecl->hasExternalStorage()) 388487454161a6377b573d4fc3ff45e7b3ec193e860cSteve Naroff Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass); 3885b31cb7f1752ea011fd06ac9574ce24667d11cbdbFariborz Jahanian } 3886682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner } 388738e24c782c17b6058bf61d635747bbde19fb1bc7Fariborz Jahanian } 388810af87932fe4bffad539b24d512a33a1803daeaeFariborz Jahanian ActOnObjCContainerFinishDefinition(); 3889b4a686df4de21ec4eeca69211b21f7fe716abeaeArgyrios Kyrtzidis 3890a3c6246950f23d7d4cd748badaf8f05d7bc3f14aFariborz Jahanian for (unsigned i = 0, e = allTUVars.size(); i != e; i++) { 389118062394db459158942ab491a88b9d52a5c0ab0dSerge Pavlov DeclGroupRef DG = allTUVars[i].get(); 3892c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) 3893c14a03dffff69b5e1c55cc118fc52d8fd9f3a28dArgyrios Kyrtzidis (*I)->setTopLevelDeclInObjCContainer(); 3894b4a686df4de21ec4eeca69211b21f7fe716abeaeArgyrios Kyrtzidis Consumer.HandleTopLevelDeclInObjCContainer(DG); 3895b4a686df4de21ec4eeca69211b21f7fe716abeaeArgyrios Kyrtzidis } 3896d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen 3897abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko ActOnDocumentableDecl(ClassDecl); 3898d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen return ClassDecl; 38994d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 39004d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 39014d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// CvtQTToAstBitMask - utility routine to produce an AST bitmask for 39024d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner/// objective-c's type qualifier from the parser version of the same info. 39031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic Decl::ObjCDeclQualifier 3904a526c5c67e5a0473c340903ee542ce570119665fTed KremenekCvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) { 390509e2c524a18435211cfbc2fb355f91e1ac43ea89John McCall return (Decl::ObjCDeclQualifier) (unsigned) PQTVal; 39064d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 39074d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 3908926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor/// \brief Check whether the declared result type of the given Objective-C 3909926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor/// method declaration is compatible with the method's class. 3910926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor/// 3911e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidisstatic Sema::ResultTypeCompatibilityKind 3912926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas GregorCheckRelatedResultTypeCompatibility(Sema &S, ObjCMethodDecl *Method, 3913926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor ObjCInterfaceDecl *CurrentClass) { 3914651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType ResultType = Method->getReturnType(); 3915651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3916926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // If an Objective-C method inherits its related result type, then its 3917926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // declared result type must be compatible with its own class type. The 3918926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // declared result type is compatible if: 3919926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (const ObjCObjectPointerType *ResultObjectType 3920926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor = ResultType->getAs<ObjCObjectPointerType>()) { 3921926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // - it is id or qualified id, or 3922926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (ResultObjectType->isObjCIdType() || 3923926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor ResultObjectType->isObjCQualifiedIdType()) 3924e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis return Sema::RTC_Compatible; 3925926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 3926926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (CurrentClass) { 3927926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (ObjCInterfaceDecl *ResultClass 3928926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor = ResultObjectType->getInterfaceDecl()) { 3929926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // - it is the same as the method's class type, or 393060ef308e51c71b760d7f598c1b763ceb7b768148Douglas Gregor if (declaresSameEntity(CurrentClass, ResultClass)) 3931e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis return Sema::RTC_Compatible; 3932926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 3933926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // - it is a superclass of the method's class type 3934926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (ResultClass->isSuperClassOf(CurrentClass)) 3935e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis return Sema::RTC_Compatible; 3936926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 3937e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor } else { 3938e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor // Any Objective-C pointer type might be acceptable for a protocol 3939e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor // method; we just don't know. 3940e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis return Sema::RTC_Unknown; 3941926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 3942926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 3943926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 3944e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis return Sema::RTC_Incompatible; 3945926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor} 3946926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 39476c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCallnamespace { 39486c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall/// A helper class for searching for methods which a particular method 39496c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall/// overrides. 39506c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCallclass OverrideSearch { 3951b732fcebcf2ce5c24a29d660e9400d7dc9f86b69Daniel Dunbarpublic: 39526c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall Sema &S; 39536c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall ObjCMethodDecl *Method; 3954b732fcebcf2ce5c24a29d660e9400d7dc9f86b69Daniel Dunbar llvm::SmallPtrSet<ObjCMethodDecl*, 4> Overridden; 39556c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall bool Recursive; 39566c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 39576c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCallpublic: 39586c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall OverrideSearch(Sema &S, ObjCMethodDecl *method) : S(S), Method(method) { 39596c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall Selector selector = method->getSelector(); 39606c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 39616c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // Bypass this search if we've never seen an instance/class method 39626c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // with this selector before. 39636c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall Sema::GlobalMethodPool::iterator it = S.MethodPool.find(selector); 39646c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall if (it == S.MethodPool.end()) { 39650ec56b7add7be643f490ea9b430823570f01b4e2Axel Naumann if (!S.getExternalSource()) return; 39665ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor S.ReadMethodPool(selector); 39675ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor 39685ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor it = S.MethodPool.find(selector); 39695ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor if (it == S.MethodPool.end()) 39705ac4b6917aa34fae6da64036539023a6155a3d48Douglas Gregor return; 39716c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 39726c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall ObjCMethodList &list = 39736c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall method->isInstanceMethod() ? it->second.first : it->second.second; 39740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (!list.getMethod()) return; 39756c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 39766c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall ObjCContainerDecl *container 39776c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall = cast<ObjCContainerDecl>(method->getDeclContext()); 39786c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 39796c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // Prevent the search from reaching this container again. This is 39806c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // important with categories, which override methods from the 39816c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // interface and each other. 3982c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(container)) { 3983c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor searchFromContainer(container); 3984dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor if (ObjCInterfaceDecl *Interface = Category->getClassInterface()) 3985dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor searchFromContainer(Interface); 3986c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor } else { 3987c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor searchFromContainer(container); 3988c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor } 3989926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 39906c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 39914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar typedef llvm::SmallPtrSetImpl<ObjCMethodDecl*>::iterator iterator; 39926c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall iterator begin() const { return Overridden.begin(); } 39936c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall iterator end() const { return Overridden.end(); } 39946c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 39956c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCallprivate: 39966c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall void searchFromContainer(ObjCContainerDecl *container) { 39976c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall if (container->isInvalidDecl()) return; 39986c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 39996c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall switch (container->getDeclKind()) { 40006c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall#define OBJCCONTAINER(type, base) \ 40016c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall case Decl::type: \ 40026c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall searchFrom(cast<type##Decl>(container)); \ 40036c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall break; 40046c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall#define ABSTRACT_DECL(expansion) 40056c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall#define DECL(type, base) \ 40066c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall case Decl::type: 40076c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall#include "clang/AST/DeclNodes.inc" 40086c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall llvm_unreachable("not an ObjC container!"); 40096c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 40106c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 40116c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 40126c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall void searchFrom(ObjCProtocolDecl *protocol) { 40135e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor if (!protocol->hasDefinition()) 40145e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor return; 40155e2a1ff9f28d2eab256d2553e76a9c9d54693875Douglas Gregor 40166c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // A method in a protocol declaration overrides declarations from 40176c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // referenced ("parent") protocols. 40186c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall search(protocol->getReferencedProtocols()); 40196c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 40206c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 40216c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall void searchFrom(ObjCCategoryDecl *category) { 40226c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // A method in a category declaration overrides declarations from 40236c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // the main class and from protocols the category references. 4024c968334510b0193ae8977c83d3ee66cbd6867639Douglas Gregor // The main class is handled in the constructor. 40256c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall search(category->getReferencedProtocols()); 40266c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 40276c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 40286c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall void searchFrom(ObjCCategoryImplDecl *impl) { 40296c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // A method in a category definition that has a category 40306c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // declaration overrides declarations from the category 40316c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // declaration. 40326c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall if (ObjCCategoryDecl *category = impl->getCategoryDecl()) { 40336c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall search(category); 4034dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor if (ObjCInterfaceDecl *Interface = category->getClassInterface()) 4035dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor search(Interface); 40366c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 40376c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // Otherwise it overrides declarations from the class. 4038dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor } else if (ObjCInterfaceDecl *Interface = impl->getClassInterface()) { 4039dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor search(Interface); 40406c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 40416c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 40426c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 40436c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall void searchFrom(ObjCInterfaceDecl *iface) { 40446c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // A method in a class declaration overrides declarations from 40452e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor if (!iface->hasDefinition()) 40462e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor return; 40472e5c15be82f362611c5928ce853d0685ff98c766Douglas Gregor 40486c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // - categories, 4049651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *Cat : iface->known_categories()) 4050651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines search(Cat); 40516c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 40526c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // - the super class, and 40536c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall if (ObjCInterfaceDecl *super = iface->getSuperClass()) 40546c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall search(super); 40556c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 40566c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // - any referenced protocols. 40576c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall search(iface->getReferencedProtocols()); 40586c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 40596c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 40606c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall void searchFrom(ObjCImplementationDecl *impl) { 40616c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // A method in a class implementation overrides declarations from 40626c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // the class interface. 4063dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor if (ObjCInterfaceDecl *Interface = impl->getClassInterface()) 4064dd87224ad67b79e9c48dd4a06779b353aa633cbbDouglas Gregor search(Interface); 40656c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 40666c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 40676c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall void search(const ObjCProtocolList &protocols) { 40686c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall for (ObjCProtocolList::iterator i = protocols.begin(), e = protocols.end(); 40696c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall i != e; ++i) 40706c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall search(*i); 40716c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 40726c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 40736c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall void search(ObjCContainerDecl *container) { 40746c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // Check for a method in this container which matches this selector. 40756c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall ObjCMethodDecl *meth = container->getMethod(Method->getSelector(), 407604593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis Method->isInstanceMethod(), 407704593d0f9d84f6adf942bd66f1587e05c6a47c42Argyrios Kyrtzidis /*AllowHidden=*/true); 40786c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 40796c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // If we find one, record it and bail out. 40806c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall if (meth) { 40816c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall Overridden.insert(meth); 40826c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall return; 40836c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 40846c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 40856c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // Otherwise, search for methods that a hypothetical method here 40866c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // would have overridden. 40876c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 40886c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall // Note that we're now in a recursive case. 40896c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall Recursive = true; 40906c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 40916c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall searchFromContainer(container); 40926c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall } 40936c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall}; 409487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} // end anonymous namespace 4095926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 4096e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidisvoid Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, 4097e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis ObjCInterfaceDecl *CurrentClass, 4098e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis ResultTypeCompatibilityKind RTC) { 4099e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // Search for overridden methods and merge information down from them. 4100e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis OverrideSearch overrides(*this, ObjCMethod); 4101e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // Keep track if the method overrides any method in the class's base classes, 4102e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // its protocols, or its categories' protocols; we will keep that info 4103e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // in the ObjCMethodDecl. 4104e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // For this info, a method in an implementation is not considered as 4105e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // overriding the same method in the interface or its categories. 4106e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis bool hasOverriddenMethodsInBaseOrProtocol = false; 4107e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis for (OverrideSearch::iterator 4108e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis i = overrides.begin(), e = overrides.end(); i != e; ++i) { 4109e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis ObjCMethodDecl *overridden = *i; 4110e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 4111e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis if (!hasOverriddenMethodsInBaseOrProtocol) { 4112e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis if (isa<ObjCProtocolDecl>(overridden->getDeclContext()) || 4113e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis CurrentClass != overridden->getClassInterface() || 4114e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis overridden->isOverriding()) { 4115e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis hasOverriddenMethodsInBaseOrProtocol = true; 4116e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis 4117e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis } else if (isa<ObjCImplDecl>(ObjCMethod->getDeclContext())) { 4118e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // OverrideSearch will return as "overridden" the same method in the 4119e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // interface. For hasOverriddenMethodsInBaseOrProtocol, we need to 4120e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // check whether a category of a base class introduced a method with the 4121e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // same selector, after the interface method declaration. 4122e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // To avoid unnecessary lookups in the majority of cases, we use the 4123e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // extra info bits in GlobalMethodPool to check whether there were any 4124e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // category methods with this selector. 4125e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis GlobalMethodPool::iterator It = 4126e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis MethodPool.find(ObjCMethod->getSelector()); 4127e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis if (It != MethodPool.end()) { 4128e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis ObjCMethodList &List = 4129e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis ObjCMethod->isInstanceMethod()? It->second.first: It->second.second; 4130e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis unsigned CategCount = List.getBits(); 4131e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis if (CategCount > 0) { 4132e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // If the method is in a category we'll do lookup if there were at 4133e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis // least 2 category methods recorded, otherwise only one will do. 4134e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis if (CategCount > 1 || 4135e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis !isa<ObjCCategoryImplDecl>(overridden->getDeclContext())) { 4136e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis OverrideSearch overrides(*this, overridden); 4137e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis for (OverrideSearch::iterator 4138e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis OI= overrides.begin(), OE= overrides.end(); OI!=OE; ++OI) { 4139e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis ObjCMethodDecl *SuperOverridden = *OI; 4140ab3d509bc45218c278454962ff644bb13d18ce1aArgyrios Kyrtzidis if (isa<ObjCProtocolDecl>(SuperOverridden->getDeclContext()) || 4141ab3d509bc45218c278454962ff644bb13d18ce1aArgyrios Kyrtzidis CurrentClass != SuperOverridden->getClassInterface()) { 4142e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis hasOverriddenMethodsInBaseOrProtocol = true; 4143e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis overridden->setOverriding(true); 4144e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis break; 4145e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis } 4146e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis } 4147e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis } 4148e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis } 4149e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis } 4150e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis } 4151e7a77727804c12750cb39e8732e26f2a26e4ce0fArgyrios Kyrtzidis } 4152e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 4153e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // Propagate down the 'related result type' bit from overridden methods. 4154e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis if (RTC != Sema::RTC_Incompatible && overridden->hasRelatedResultType()) 4155e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis ObjCMethod->SetRelatedResultType(); 4156e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 4157e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // Then merge the declarations. 4158e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis mergeObjCMethodDecls(ObjCMethod, overridden); 4159e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 4160e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis if (ObjCMethod->isImplicit() && overridden->isImplicit()) 4161e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis continue; // Conflicting properties are detected elsewhere. 4162e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 4163e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // Check for overriding methods 4164e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis if (isa<ObjCInterfaceDecl>(ObjCMethod->getDeclContext()) || 4165e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis isa<ObjCImplementationDecl>(ObjCMethod->getDeclContext())) 4166e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis CheckConflictingOverridingMethod(ObjCMethod, overridden, 4167e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis isa<ObjCProtocolDecl>(overridden->getDeclContext())); 4168e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 4169e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis if (CurrentClass && overridden->getDeclContext() != CurrentClass && 4170c4133a477389dacb4479a96ee2227b92aea0a237Fariborz Jahanian isa<ObjCInterfaceDecl>(overridden->getDeclContext()) && 4171c4133a477389dacb4479a96ee2227b92aea0a237Fariborz Jahanian !overridden->isImplicit() /* not meant for properties */) { 4172e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis ObjCMethodDecl::param_iterator ParamI = ObjCMethod->param_begin(), 4173e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis E = ObjCMethod->param_end(); 41740a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor ObjCMethodDecl::param_iterator PrevI = overridden->param_begin(), 41750a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor PrevE = overridden->param_end(); 41760a4a23a6afd6db4bdcedd4e9f39d8baf4a446f15Douglas Gregor for (; ParamI != E && PrevI != PrevE; ++ParamI, ++PrevI) { 4177e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis assert(PrevI != overridden->param_end() && "Param mismatch"); 4178e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis QualType T1 = Context.getCanonicalType((*ParamI)->getType()); 4179e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis QualType T2 = Context.getCanonicalType((*PrevI)->getType()); 4180e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // If type of argument of method in this class does not match its 4181e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis // respective argument type in the super class method, issue warning; 4182e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis if (!Context.typesAreCompatible(T1, T2)) { 4183e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis Diag((*ParamI)->getLocation(), diag::ext_typecheck_base_super) 4184e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis << T1 << T2; 4185e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis Diag(overridden->getLocation(), diag::note_previous_declaration); 4186e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis break; 4187e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis } 4188e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis } 4189e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis } 4190e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis } 4191e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 4192e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis ObjCMethod->setOverriding(hasOverriddenMethodsInBaseOrProtocol); 4193e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis} 4194e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 419587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// Merge type nullability from for a redeclaration of the same entity, 419687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// producing the updated type of the redeclared entity. 419787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstatic QualType mergeTypeNullabilityForRedecl(Sema &S, SourceLocation loc, 419887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar QualType type, 419987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar bool usesCSKeyword, 420087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation prevLoc, 420187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar QualType prevType, 420287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar bool prevUsesCSKeyword) { 420387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Determine the nullability of both types. 420487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto nullability = type->getNullability(S.Context); 420587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto prevNullability = prevType->getNullability(S.Context); 420687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 420787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Easy case: both have nullability. 420887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (nullability.hasValue() == prevNullability.hasValue()) { 420987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Neither has nullability; continue. 421087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!nullability) 421187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return type; 421287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 421387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // The nullabilities are equivalent; do nothing. 421487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (*nullability == *prevNullability) 421587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return type; 421687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 421787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Complain about mismatched nullability. 421887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.Diag(loc, diag::err_nullability_conflicting) 421987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << DiagNullabilityKind(*nullability, usesCSKeyword) 422087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << DiagNullabilityKind(*prevNullability, prevUsesCSKeyword); 422187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return type; 422287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 422387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 422487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // If it's the redeclaration that has nullability, don't change anything. 422587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (nullability) 422687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return type; 422787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 422887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Otherwise, provide the result with the same nullability. 422987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return S.Context.getAttributedType( 423087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar AttributedType::getNullabilityAttrKind(*prevNullability), 423187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar type, type); 423287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} 423387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 423487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// Merge information from the declaration of a method in the \@interface 423587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// (or a category/extension) into the corresponding method in the 423687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar/// @implementation (for a class or category). 423787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarstatic void mergeInterfaceMethodToImpl(Sema &S, 423887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCMethodDecl *method, 423987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCMethodDecl *prevMethod) { 424087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Merge the objc_requires_super attribute. 424187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (prevMethod->hasAttr<ObjCRequiresSuperAttr>() && 424287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar !method->hasAttr<ObjCRequiresSuperAttr>()) { 424387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // merge the attribute into implementation. 424487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar method->addAttr( 424587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCRequiresSuperAttr::CreateImplicit(S.Context, 424687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar method->getLocation())); 424787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 424887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 424987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Merge nullability of the result type. 425087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar QualType newReturnType 425187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar = mergeTypeNullabilityForRedecl( 425287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S, method->getReturnTypeSourceRange().getBegin(), 425387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar method->getReturnType(), 425487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar method->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability, 425587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar prevMethod->getReturnTypeSourceRange().getBegin(), 425687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar prevMethod->getReturnType(), 425787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar prevMethod->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability); 425887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar method->setReturnType(newReturnType); 425987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 426087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Handle each of the parameters. 426187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar unsigned numParams = method->param_size(); 426287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar unsigned numPrevParams = prevMethod->param_size(); 426387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar for (unsigned i = 0, n = std::min(numParams, numPrevParams); i != n; ++i) { 426487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ParmVarDecl *param = method->param_begin()[i]; 426587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ParmVarDecl *prevParam = prevMethod->param_begin()[i]; 426687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 426787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Merge nullability. 426887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar QualType newParamType 426987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar = mergeTypeNullabilityForRedecl( 427087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S, param->getLocation(), param->getType(), 427187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar param->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability, 427287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar prevParam->getLocation(), prevParam->getType(), 427387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar prevParam->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability); 427487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar param->setType(newParamType); 427587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 427687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} 427787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 4278d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema::ActOnMethodDeclaration( 42797f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian Scope *S, 42804d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner SourceLocation MethodLoc, SourceLocation EndLoc, 4281a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian tok::TokenKind MethodType, 4282b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ObjCDeclSpec &ReturnQT, ParsedType ReturnType, 428311d77169555480ee0a04c6e5bc390d8fde41175dArgyrios Kyrtzidis ArrayRef<SourceLocation> SelectorLocs, 42844d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner Selector Sel, 42854d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // optional arguments. The number of types/arguments is obtained 42864d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // from the Sel.getNumArgs(). 4287e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner ObjCArgInfo *ArgInfo, 42884f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args 42894d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind, 429090ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian bool isVariadic, bool MethodDefinition) { 4291da323adbb99cee19a203ead852d5d9bfebb23fb7Steve Naroff // Make sure we can establish a context for the method. 4292a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian if (!CurContext->isObjCContainer()) { 4293da323adbb99cee19a203ead852d5d9bfebb23fb7Steve Naroff Diag(MethodLoc, diag::error_missing_method_context); 42946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 4295da323adbb99cee19a203ead852d5d9bfebb23fb7Steve Naroff } 4296a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext); 4297a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian Decl *ClassDecl = cast<Decl>(OCD); 42980ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner QualType resultDeclType; 42991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4300e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor bool HasRelatedResultType = false; 43016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TypeSourceInfo *ReturnTInfo = nullptr; 4302ccef371a67756233aa97770e4fccdfa868b3e2d0Steve Naroff if (ReturnType) { 4303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines resultDeclType = GetTypeFromParser(ReturnType, &ReturnTInfo); 43041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4305ddb5a3926d715ab4354ca36117679e3f4d5d3e21Eli Friedman if (CheckFunctionReturnType(resultDeclType, MethodLoc)) 43066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 4307ddb5a3926d715ab4354ca36117679e3f4d5d3e21Eli Friedman 430887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar QualType bareResultType = resultDeclType; 430987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar (void)AttributedType::stripOuterNullability(bareResultType); 431087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar HasRelatedResultType = (bareResultType == Context.getObjCInstanceType()); 4311aab24a616de59c543d78d7636f22fb786053fefaFariborz Jahanian } else { // get the type for "id". 43120ed844b04ea4387caa4e1cf3dc375d269657536bChris Lattner resultDeclType = Context.getObjCIdType(); 4313feb4fa165c5e8c40ffc8b1b655cc3c8071862b20Fariborz Jahanian Diag(MethodLoc, diag::warn_missing_method_return_type) 431411d77169555480ee0a04c6e5bc390d8fde41175dArgyrios Kyrtzidis << FixItHint::CreateInsertion(SelectorLocs.front(), "(id)"); 4315aab24a616de59c543d78d7636f22fb786053fefaFariborz Jahanian } 43161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4317651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCMethodDecl *ObjCMethod = ObjCMethodDecl::Create( 4318651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Context, MethodLoc, EndLoc, Sel, resultDeclType, ReturnTInfo, CurContext, 4319651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MethodType == tok::minus, isVariadic, 4320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /*isPropertyAccessor=*/false, 4321651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /*isImplicitlyDeclared=*/false, /*isDefined=*/false, 4322651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MethodDeclKind == tok::objc_optional ? ObjCMethodDecl::Optional 4323651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : ObjCMethodDecl::Required, 4324651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HasRelatedResultType); 43251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 43265f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<ParmVarDecl*, 16> Params; 43271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 43287db638d1222bfb2517ac54388e83169a4c76cf7eChris Lattner for (unsigned i = 0, e = Sel.getNumArgs(); i != e; ++i) { 432958e4677a948e80c92deeebbcd3bdd9266adda798John McCall QualType ArgType; 4330a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TypeSourceInfo *DI; 43311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 43327247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie if (!ArgInfo[i].Type) { 433358e4677a948e80c92deeebbcd3bdd9266adda798John McCall ArgType = Context.getObjCIdType(); 43346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines DI = nullptr; 4335e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner } else { 433658e4677a948e80c92deeebbcd3bdd9266adda798John McCall ArgType = GetTypeFromParser(ArgInfo[i].Type, &DI); 4337e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner } 43381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 43397f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian LookupResult R(*this, ArgInfo[i].Name, ArgInfo[i].NameLoc, 43407f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian LookupOrdinaryName, ForRedeclaration); 43417f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian LookupName(R, S); 43427f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian if (R.isSingleResult()) { 43437f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian NamedDecl *PrevDecl = R.getFoundDecl(); 43447f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian if (S->isDeclScope(PrevDecl)) { 434590ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian Diag(ArgInfo[i].NameLoc, 434690ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian (MethodDefinition ? diag::warn_method_param_redefinition 434790ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian : diag::warn_method_param_declaration)) 43487f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian << ArgInfo[i].Name; 43497f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian Diag(PrevDecl->getLocation(), 43507f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian diag::note_previous_declaration); 43517f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian } 43527f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian } 43537f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian 4354ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara SourceLocation StartLoc = DI 4355ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara ? DI->getTypeLoc().getBeginLoc() 4356ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara : ArgInfo[i].NameLoc; 4357ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara 435881ef3e664d8ae250fbb68b2b6ccdeebb6c13ede5John McCall ParmVarDecl* Param = CheckParameter(ObjCMethod, StartLoc, 435981ef3e664d8ae250fbb68b2b6ccdeebb6c13ede5John McCall ArgInfo[i].NameLoc, ArgInfo[i].Name, 4360d2615cc53b916e8aae45783ca7113b93de515ce3Rafael Espindola ArgType, DI, SC_None); 43611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 43627079886ab5a9df450ed773419f0ae81f8404e2aaJohn McCall Param->setObjCMethodScopeInfo(i); 43637079886ab5a9df450ed773419f0ae81f8404e2aaJohn McCall 4364a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek Param->setObjCDeclQualifier( 4365e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier())); 43661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4367f97e8fa2966e3e49eac433336450f24ccbdf8b4aChris Lattner // Apply the attributes to the parameter. 43689cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs); 43691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 437047b1d96bde79633d4aeded1cde2c5f870a58af24Fariborz Jahanian if (Param->hasAttr<BlocksAttr>()) { 437147b1d96bde79633d4aeded1cde2c5f870a58af24Fariborz Jahanian Diag(Param->getLocation(), diag::err_block_on_nonlocal); 437247b1d96bde79633d4aeded1cde2c5f870a58af24Fariborz Jahanian Param->setInvalidDecl(); 437347b1d96bde79633d4aeded1cde2c5f870a58af24Fariborz Jahanian } 43747f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian S->AddDecl(Param); 43757f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian IdResolver.AddDecl(Param); 43767f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian 43774d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner Params.push_back(Param); 43784d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 43797f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian 43804f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian for (unsigned i = 0, e = CNumArgs; i != e; ++i) { 4381d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall ParmVarDecl *Param = cast<ParmVarDecl>(CParamInfo[i].Param); 43824f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian QualType ArgType = Param->getType(); 43834f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian if (ArgType.isNull()) 43844f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian ArgType = Context.getObjCIdType(); 43854f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian else 43864f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian // Perform the default array/function conversions (C99 6.7.5.3p[7,8]). 438779e6bd379773447a74cc3e579d9081e4c5cb6d63Douglas Gregor ArgType = Context.getAdjustedParameterType(ArgType); 4388ddb5a3926d715ab4354ca36117679e3f4d5d3e21Eli Friedman 43894f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian Param->setDeclContext(ObjCMethod); 43904f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian Params.push_back(Param); 43914f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian } 43924f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian 4393491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis ObjCMethod->setMethodParams(Context, Params, SelectorLocs); 4394a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek ObjCMethod->setObjCDeclQualifier( 4395a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier())); 43963568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 43973568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (AttrList) 43989cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList); 43991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4400bdb2d5056fd675c27307b34efd371bbba6839e92Douglas Gregor // Add the method now. 44016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const ObjCMethodDecl *PrevMethod = nullptr; 44026c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall if (ObjCImplDecl *ImpDecl = dyn_cast<ObjCImplDecl>(ClassDecl)) { 44034d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (MethodType == tok::minus) { 440417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis PrevMethod = ImpDecl->getInstanceMethod(Sel); 440517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis ImpDecl->addInstanceMethod(ObjCMethod); 44064d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } else { 440717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis PrevMethod = ImpDecl->getClassMethod(Sel); 440817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis ImpDecl->addClassMethod(ObjCMethod); 44094d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 4410926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 441187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Merge information from the @interface declaration into the 441287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // @implementation. 441387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface()) { 441487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto *IMD = IDecl->lookupMethod(ObjCMethod->getSelector(), 441587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCMethod->isInstanceMethod())) { 441687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar mergeInterfaceMethodToImpl(*this, ObjCMethod, IMD); 441787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 441887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Warn about defining -dealloc in a category. 441987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (isa<ObjCCategoryImplDecl>(ImpDecl) && IMD->isOverriding() && 442087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCMethod->getSelector().getMethodFamily() == OMF_dealloc) { 442187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diag(ObjCMethod->getLocation(), diag::warn_dealloc_in_category) 442287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar << ObjCMethod->getDeclName(); 442387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 442487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 4425ec236787c5868eef53a807ca1a68b6b0b8c604c6Fariborz Jahanian } 4426bdb2d5056fd675c27307b34efd371bbba6839e92Douglas Gregor } else { 4427bdb2d5056fd675c27307b34efd371bbba6839e92Douglas Gregor cast<DeclContext>(ClassDecl)->addDecl(ObjCMethod); 44284d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner } 44296c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 44304d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner if (PrevMethod) { 44314d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner // You can never have two method definitions with the same name. 44325f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(ObjCMethod->getLocation(), diag::err_duplicate_method_decl) 4433077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner << ObjCMethod->getDeclName(); 44345f4a6829dc58cab2f76e2b98492859aa3b91e3f2Chris Lattner Diag(PrevMethod->getLocation(), diag::note_previous_declaration); 4435fbff0c4510c7f0e0f30a005960e434b973f5bd21Fariborz Jahanian ObjCMethod->setInvalidDecl(); 4436fbff0c4510c7f0e0f30a005960e434b973f5bd21Fariborz Jahanian return ObjCMethod; 44371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 443854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 4439926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // If this Objective-C method does not have a related result type, but we 4440926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // are allowed to infer related result types, try to do so based on the 4441926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor // method family. 4442926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor ObjCInterfaceDecl *CurrentClass = dyn_cast<ObjCInterfaceDecl>(ClassDecl); 4443926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (!CurrentClass) { 4444926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(ClassDecl)) 4445926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor CurrentClass = Cat->getClassInterface(); 4446926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor else if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(ClassDecl)) 4447926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor CurrentClass = Impl->getClassInterface(); 4448926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor else if (ObjCCategoryImplDecl *CatImpl 4449926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor = dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) 4450926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor CurrentClass = CatImpl->getClassInterface(); 4451926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 44526c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 4453e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor ResultTypeCompatibilityKind RTC 4454e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor = CheckRelatedResultTypeCompatibility(*this, ObjCMethod, CurrentClass); 44556c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 4456e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis CheckObjCMethodOverrides(ObjCMethod, CurrentClass, RTC); 44576c2c250db1e2d0138bbfaadbbec3118db7e8a8c9John McCall 4458f85e193739c953358c865005855253af4f68a497John McCall bool ARCError = false; 44594e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjCAutoRefCount) 4460b846381fc3099b2340ba8c74d16178203a60d9a0John McCall ARCError = CheckARCMethodDecl(ObjCMethod); 4461f85e193739c953358c865005855253af4f68a497John McCall 4462e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor // Infer the related result type when possible. 4463e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis if (!ARCError && RTC == Sema::RTC_Compatible && 4464e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor !ObjCMethod->hasRelatedResultType() && 4465e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor LangOpts.ObjCInferRelatedResultType) { 4466926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor bool InferRelatedResultType = false; 4467926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor switch (ObjCMethod->getMethodFamily()) { 4468926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_None: 4469926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_copy: 4470926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_dealloc: 447180cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber case OMF_finalize: 4472926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_mutableCopy: 4473926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_release: 4474926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_retainCount: 4475176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case OMF_initialize: 44769670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian case OMF_performSelector: 4477926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor break; 4478926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 4479926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_alloc: 4480926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_new: 448158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar InferRelatedResultType = ObjCMethod->isClassMethod(); 4482926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor break; 4483926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 4484926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_init: 4485926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_autorelease: 4486926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_retain: 4487926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor case OMF_self: 4488926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor InferRelatedResultType = ObjCMethod->isInstanceMethod(); 4489926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor break; 4490926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 4491926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor 449258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar if (InferRelatedResultType && 449358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar !ObjCMethod->getReturnType()->isObjCIndependentClassType()) 4494926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor ObjCMethod->SetRelatedResultType(); 4495926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor } 4496a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 4497a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko ActOnDocumentableDecl(ObjCMethod); 4498a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 4499d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return ObjCMethod; 45004d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner} 45014d3914836e85258e9ace7306999413e3c7ea6c11Chris Lattner 4502cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattnerbool Sema::CheckObjCDeclScope(Decl *D) { 450358a764940df0cd41767367eb2f4fced6f374176bFariborz Jahanian // Following is also an error. But it is caused by a missing @end 450458a764940df0cd41767367eb2f4fced6f374176bFariborz Jahanian // and diagnostic is issued elsewhere. 4505fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis if (isa<ObjCContainerDecl>(CurContext->getRedeclContext())) 4506fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis return false; 4507fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis 4508fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis // If we switched context to translation unit while we are still lexically in 4509fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis // an objc container, it means the parser missed emitting an error. 4510fce79ebc6c16676b106ade71356b3adfc11493e7Argyrios Kyrtzidis if (isa<TranslationUnitDecl>(getCurLexicalContext()->getRedeclContext())) 4511a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian return false; 4512a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian 451315281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope); 451415281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson D->setInvalidDecl(); 45151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 451615281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson return true; 451715281450f512b7d554858e4d17fca00bfc442a07Anders Carlsson} 4518cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner 45191dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// Called whenever \@defs(ClassName) is encountered in the source. Inserts the 4520cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner/// instance variables of ClassName into Decls. 4521d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Sema::ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, 4522cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner IdentifierInfo *ClassName, 45235f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<Decl*> &Decls) { 4524cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner // Check that ClassName is a valid class 4525c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor ObjCInterfaceDecl *Class = getObjCInterfaceDecl(ClassName, DeclStart); 4526cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner if (!Class) { 4527cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner Diag(DeclStart, diag::err_undef_interface) << ClassName; 4528cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner return; 4529cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner } 4530260611a32535c851237926bfcf78869b13c07d5bJohn McCall if (LangOpts.ObjCRuntime.isNonFragile()) { 45310468fb99068c40990a3b1451938fee5b90daf941Fariborz Jahanian Diag(DeclStart, diag::err_atdef_nonfragile_interface); 45320468fb99068c40990a3b1451938fee5b90daf941Fariborz Jahanian return; 45330468fb99068c40990a3b1451938fee5b90daf941Fariborz Jahanian } 45341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4535cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner // Collect the instance variables 4536db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose SmallVector<const ObjCIvarDecl*, 32> Ivars; 45372c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian Context.DeepCollectObjCIvars(Class, true, Ivars); 45384183335fa8bfce8dd2d910dc992dace8c5f66b0dFariborz Jahanian // For each ivar, create a fresh ObjCAtDefsFieldDecl. 45392c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian for (unsigned i = 0; i < Ivars.size(); i++) { 4540db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose const FieldDecl* ID = cast<FieldDecl>(Ivars[i]); 4541d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall RecordDecl *Record = dyn_cast<RecordDecl>(TagD); 4542ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara Decl *FD = ObjCAtDefsFieldDecl::Create(Context, Record, 4543ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara /*FIXME: StartL=*/ID->getLocation(), 4544ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara ID->getLocation(), 45454183335fa8bfce8dd2d910dc992dace8c5f66b0dFariborz Jahanian ID->getIdentifier(), ID->getType(), 45464183335fa8bfce8dd2d910dc992dace8c5f66b0dFariborz Jahanian ID->getBitWidth()); 4547d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decls.push_back(FD); 45484183335fa8bfce8dd2d910dc992dace8c5f66b0dFariborz Jahanian } 45491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4550cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner // Introduce all of these fields into the appropriate scope. 45515f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner for (SmallVectorImpl<Decl*>::iterator D = Decls.begin(); 4552cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner D != Decls.end(); ++D) { 4553d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall FieldDecl *FD = cast<FieldDecl>(*D); 45544e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus) 4555cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner PushOnScopeChains(cast<FieldDecl>(FD), S); 4556d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD)) 455717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis Record->addDecl(FD); 4558cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner } 4559cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner} 4560cc98eac383718899462b9b1361c46eea8dddfb2bChris Lattner 4561160b5630aa781ac348303e1ae088d27016637778Douglas Gregor/// \brief Build a type-check a new Objective-C exception variable declaration. 4562ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo BagnaraVarDecl *Sema::BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType T, 4563ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara SourceLocation StartLoc, 4564ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara SourceLocation IdLoc, 4565ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara IdentifierInfo *Id, 4566160b5630aa781ac348303e1ae088d27016637778Douglas Gregor bool Invalid) { 4567160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // ISO/IEC TR 18037 S6.7.3: "The type of an object with automatic storage 4568160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // duration shall not be qualified by an address-space qualifier." 4569160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // Since all parameters have automatic store duration, they can not have 4570160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // an address space. 4571160b5630aa781ac348303e1ae088d27016637778Douglas Gregor if (T.getAddressSpace() != 0) { 4572ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara Diag(IdLoc, diag::err_arg_with_address_space); 4573160b5630aa781ac348303e1ae088d27016637778Douglas Gregor Invalid = true; 4574160b5630aa781ac348303e1ae088d27016637778Douglas Gregor } 4575160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 4576160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // An @catch parameter must be an unqualified object pointer type; 4577160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // FIXME: Recover from "NSObject foo" by inserting the * in "NSObject *foo"? 4578160b5630aa781ac348303e1ae088d27016637778Douglas Gregor if (Invalid) { 4579160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // Don't do any further checking. 4580be270a0fae647ae3fb4d6a21ba1ea5ab9c40853aDouglas Gregor } else if (T->isDependentType()) { 4581be270a0fae647ae3fb4d6a21ba1ea5ab9c40853aDouglas Gregor // Okay: we don't know what this type will instantiate to. 4582160b5630aa781ac348303e1ae088d27016637778Douglas Gregor } else if (!T->isObjCObjectPointerType()) { 4583160b5630aa781ac348303e1ae088d27016637778Douglas Gregor Invalid = true; 4584ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara Diag(IdLoc ,diag::err_catch_param_not_objc_type); 4585160b5630aa781ac348303e1ae088d27016637778Douglas Gregor } else if (T->isObjCQualifiedIdType()) { 4586160b5630aa781ac348303e1ae088d27016637778Douglas Gregor Invalid = true; 4587ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara Diag(IdLoc, diag::err_illegal_qualifiers_on_catch_parm); 4588160b5630aa781ac348303e1ae088d27016637778Douglas Gregor } 4589160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 4590ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara VarDecl *New = VarDecl::Create(Context, CurContext, StartLoc, IdLoc, Id, 4591d2615cc53b916e8aae45783ca7113b93de515ce3Rafael Espindola T, TInfo, SC_None); 4592324b54d3f60d92a82815512119791ce1c285b63eDouglas Gregor New->setExceptionVariable(true); 4593324b54d3f60d92a82815512119791ce1c285b63eDouglas Gregor 45949aab9c4116bb3ea876d92d4af10bff7f4c451f24Douglas Gregor // In ARC, infer 'retaining' for variables of retainable type. 45954e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(New)) 45969aab9c4116bb3ea876d92d4af10bff7f4c451f24Douglas Gregor Invalid = true; 45979aab9c4116bb3ea876d92d4af10bff7f4c451f24Douglas Gregor 4598160b5630aa781ac348303e1ae088d27016637778Douglas Gregor if (Invalid) 4599160b5630aa781ac348303e1ae088d27016637778Douglas Gregor New->setInvalidDecl(); 4600160b5630aa781ac348303e1ae088d27016637778Douglas Gregor return New; 4601160b5630aa781ac348303e1ae088d27016637778Douglas Gregor} 4602160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 4603d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) { 4604160b5630aa781ac348303e1ae088d27016637778Douglas Gregor const DeclSpec &DS = D.getDeclSpec(); 4605160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 4606160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // We allow the "register" storage class on exception variables because 4607160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // GCC did, but we drop it completely. Any other storage class is an error. 4608160b5630aa781ac348303e1ae088d27016637778Douglas Gregor if (DS.getStorageClassSpec() == DeclSpec::SCS_register) { 4609160b5630aa781ac348303e1ae088d27016637778Douglas Gregor Diag(DS.getStorageClassSpecLoc(), diag::warn_register_objc_catch_parm) 4610160b5630aa781ac348303e1ae088d27016637778Douglas Gregor << FixItHint::CreateRemoval(SourceRange(DS.getStorageClassSpecLoc())); 4611ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith } else if (DeclSpec::SCS SCS = DS.getStorageClassSpec()) { 4612160b5630aa781ac348303e1ae088d27016637778Douglas Gregor Diag(DS.getStorageClassSpecLoc(), diag::err_storage_spec_on_catch_parm) 4613ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith << DeclSpec::getSpecifierName(SCS); 4614ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith } 46154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (DS.isInlineSpecified()) 46164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar Diag(DS.getInlineSpecLoc(), diag::err_inline_non_function) 46174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar << getLangOpts().CPlusPlus1z; 4618ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec()) 4619ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), 4620ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith diag::err_invalid_thread) 4621ec64244f5939fa81596fbeddad966cca4b4a4c51Richard Smith << DeclSpec::getSpecifierName(TSCS); 4622160b5630aa781ac348303e1ae088d27016637778Douglas Gregor D.getMutableDeclSpec().ClearStorageClassSpecs(); 4623160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 4624c7f811638f8603fa373d2be724e8b1c8ba51ad75Richard Smith DiagnoseFunctionSpecifiers(D.getDeclSpec()); 4625160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 4626160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // Check that there are no default arguments inside the type of this 4627160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // exception object (C++ only). 46284e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus) 4629160b5630aa781ac348303e1ae088d27016637778Douglas Gregor CheckExtraCXXDefaultArguments(D); 4630160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 46313215398dc9dac2be19a9fc1df929e6b7d83eafcaArgyrios Kyrtzidis TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 4632bf1a028246d884a540aeafa38e89be59a269b072John McCall QualType ExceptionType = TInfo->getType(); 4633160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 4634ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara VarDecl *New = BuildObjCExceptionDecl(TInfo, ExceptionType, 4635ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara D.getSourceRange().getBegin(), 4636ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara D.getIdentifierLoc(), 4637ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara D.getIdentifier(), 4638160b5630aa781ac348303e1ae088d27016637778Douglas Gregor D.isInvalidType()); 4639160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 4640160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // Parameter declarators cannot be qualified (C++ [dcl.meaning]p1). 4641160b5630aa781ac348303e1ae088d27016637778Douglas Gregor if (D.getCXXScopeSpec().isSet()) { 4642160b5630aa781ac348303e1ae088d27016637778Douglas Gregor Diag(D.getIdentifierLoc(), diag::err_qualified_objc_catch_parm) 4643160b5630aa781ac348303e1ae088d27016637778Douglas Gregor << D.getCXXScopeSpec().getRange(); 4644160b5630aa781ac348303e1ae088d27016637778Douglas Gregor New->setInvalidDecl(); 4645160b5630aa781ac348303e1ae088d27016637778Douglas Gregor } 4646160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 4647160b5630aa781ac348303e1ae088d27016637778Douglas Gregor // Add the parameter declaration into this scope. 4648d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall S->AddDecl(New); 4649160b5630aa781ac348303e1ae088d27016637778Douglas Gregor if (D.getIdentifier()) 4650160b5630aa781ac348303e1ae088d27016637778Douglas Gregor IdResolver.AddDecl(New); 4651160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 4652160b5630aa781ac348303e1ae088d27016637778Douglas Gregor ProcessDeclAttributes(S, New, D); 4653160b5630aa781ac348303e1ae088d27016637778Douglas Gregor 4654160b5630aa781ac348303e1ae088d27016637778Douglas Gregor if (New->hasAttr<BlocksAttr>()) 4655160b5630aa781ac348303e1ae088d27016637778Douglas Gregor Diag(New->getLocation(), diag::err_block_on_nonlocal); 4656d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return New; 46574e6c0d19b7c072758922cf80525a81aeefc6e64bDouglas Gregor} 4658786cd154f2a48d2b464679d33fcd5df0cd794c06Fariborz Jahanian 4659786cd154f2a48d2b464679d33fcd5df0cd794c06Fariborz Jahanian/// CollectIvarsToConstructOrDestruct - Collect those ivars which require 4660e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian/// initialization. 46612c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanianvoid Sema::CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, 46625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<ObjCIvarDecl*> &Ivars) { 46632c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian for (ObjCIvarDecl *Iv = OI->all_declared_ivar_begin(); Iv; 46642c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian Iv= Iv->getNextIvar()) { 4665786cd154f2a48d2b464679d33fcd5df0cd794c06Fariborz Jahanian QualType QT = Context.getBaseElementType(Iv->getType()); 466668dd3ee3b5ae5b7694b4a21e34b4355431ed0457Douglas Gregor if (QT->isRecordType()) 46672c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian Ivars.push_back(Iv); 4668786cd154f2a48d2b464679d33fcd5df0cd794c06Fariborz Jahanian } 4669786cd154f2a48d2b464679d33fcd5df0cd794c06Fariborz Jahanian} 4670e4498c6d66a8f472cba29b6158a2e86dfc60d0efFariborz Jahanian 46713fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanianvoid Sema::DiagnoseUseOfUnimplementedSelectors() { 46725b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor // Load referenced selectors from the external source. 46735b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor if (ExternalSource) { 46745b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor SmallVector<std::pair<Selector, SourceLocation>, 4> Sels; 46755b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor ExternalSource->ReadReferencedSelectors(Sels); 46765b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor for (unsigned I = 0, N = Sels.size(); I != N; ++I) 46775b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor ReferencedSelectors[Sels[I].first] = Sels[I].second; 46785b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor } 46795b9dc7caaef0469babc45dd8e713727a136ce517Douglas Gregor 46808b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian // Warning will be issued only when selector table is 46818b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian // generated (which means there is at lease one implementation 46828b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian // in the TU). This is to match gcc's behavior. 46838b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian if (ReferencedSelectors.empty() || 46848b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian !Context.AnyObjCImplementation()) 46853fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian return; 46863ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar for (auto &SelectorAndLocation : ReferencedSelectors) { 46873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Selector Sel = SelectorAndLocation.first; 46883ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar SourceLocation Loc = SelectorAndLocation.second; 46893fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian if (!LookupImplementedMethodInGlobalPool(Sel)) 46903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar Diag(Loc, diag::warn_unimplemented_selector) << Sel; 46913fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian } 46923fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian} 46934e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian 46944e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz JahanianObjCIvarDecl * 46954e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz JahanianSema::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, 46964e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian const ObjCPropertyDecl *&PDecl) const { 4697651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Method->isClassMethod()) 46986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 46994e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian const ObjCInterfaceDecl *IDecl = Method->getClassInterface(); 47004e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian if (!IDecl) 47016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 4702651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Method = IDecl->lookupMethod(Method->getSelector(), /*isInstance=*/true, 4703651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /*shallowCategoryLookup=*/false, 4704651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /*followSuper=*/false); 47054e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian if (!Method || !Method->isPropertyAccessor()) 47066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 4707651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if ((PDecl = Method->findPropertyDecl())) 4708651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl()) { 4709651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // property backing ivar must belong to property's class 4710651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // or be a private ivar in class's implementation. 4711651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // FIXME. fix the const-ness issue. 4712651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IV = const_cast<ObjCInterfaceDecl *>(IDecl)->lookupInstanceVariable( 4713651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IV->getIdentifier()); 4714651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return IV; 4715651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 47166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 47174e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian} 47184e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian 4719651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace { 4720651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Used by Sema::DiagnoseUnusedBackingIvarInAccessor to check if a property 4721651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// accessor references the backing ivar. 4722651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines class UnusedBackingIvarChecker : 472387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar public RecursiveASTVisitor<UnusedBackingIvarChecker> { 4724651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines public: 4725651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Sema &S; 4726651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ObjCMethodDecl *Method; 4727651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ObjCIvarDecl *IvarD; 4728651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool AccessedIvar; 4729651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool InvokedSelfMethod; 4730651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4731651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines UnusedBackingIvarChecker(Sema &S, const ObjCMethodDecl *Method, 4732651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ObjCIvarDecl *IvarD) 4733651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : S(S), Method(Method), IvarD(IvarD), 4734651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AccessedIvar(false), InvokedSelfMethod(false) { 4735651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(IvarD); 4736651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4737651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4738651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { 4739651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (E->getDecl() == IvarD) { 4740651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AccessedIvar = true; 4741651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 4742651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4743651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 4744651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4745651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4746651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool VisitObjCMessageExpr(ObjCMessageExpr *E) { 4747651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (E->getReceiverKind() == ObjCMessageExpr::Instance && 4748651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.isSelfExpr(E->getInstanceReceiver(), Method)) { 4749651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines InvokedSelfMethod = true; 4750651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4751651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 4752651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4753651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines }; 475487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} // end anonymous namespace 4755651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4756651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Sema::DiagnoseUnusedBackingIvarInAccessor(Scope *S, 4757651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ObjCImplementationDecl *ImplD) { 4758651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (S->hasUnrecoverableErrorOccurred()) 47594e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian return; 4760651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4761651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto *CurMethod : ImplD->instance_methods()) { 4762651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned DIAG = diag::warn_unused_property_backing_ivar; 4763651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation Loc = CurMethod->getLocation(); 4764c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Diags.isIgnored(DIAG, Loc)) 4765651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 4766651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4767651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ObjCPropertyDecl *PDecl; 4768651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ObjCIvarDecl *IV = GetIvarBackingPropertyAccessor(CurMethod, PDecl); 4769651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!IV) 4770651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 4771651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4772651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines UnusedBackingIvarChecker Checker(*this, CurMethod, IV); 4773651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Checker.TraverseStmt(CurMethod->getBody()); 4774651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Checker.AccessedIvar) 4775651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 4776651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4777651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Do not issue this warning if backing ivar is used somewhere and accessor 4778651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // implementation makes a self call. This is to prevent false positive in 4779651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // cases where the ivar is accessed by another method that the accessor 4780651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // delegates to. 4781651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!IV->isReferenced() || !Checker.InvokedSelfMethod) { 4782651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diag(Loc, DIAG) << IV; 4783651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diag(PDecl->getLocation(), diag::note_property_declare); 4784651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 47854e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian } 47864e7f00c74487bca84993a1f35d0a26a84ed2b1a0Fariborz Jahanian} 4787