rsmith created this revision. Herald added subscribers: javed.absar, sanjoy.
Determining whether a declaration is visible or not requires knowledge of the context in which the question is asked: for instance, during template instantiation, additional modules might be visible, and with local submodule visibility, the set of visible declarations can shrink as well as grow throughout the compilation. This patch explicitly passes an "is hidden" callback to all ObjC lookup functions on Decl rather than relying on the increasingly-inaccurate Hidden bit to provide useful information. (Ideally, these lookup functions would be moved to Sema instead; that change can follow if it makes sense.) Please pay particular attention to the places where `AllDeclsVisible` is passed: in those places, we do not have any local visibility context. Possibly some of them should be doing something more subtle than ignoring module visibility rules. The test from PR33552 does /not/ pass with this change, I'm still digging into what else might be wrong here. Repository: rL LLVM https://reviews.llvm.org/D34494 Files: include/clang/AST/DeclObjC.h include/clang/Sema/Sema.h lib/ARCMigrate/ObjCMT.cpp lib/AST/ASTContext.cpp lib/AST/DeclObjC.cpp lib/Analysis/BodyFarm.cpp lib/Analysis/CallGraph.cpp lib/CodeGen/CGObjCMac.cpp lib/CodeGen/CodeGenModule.cpp lib/Edit/RewriteObjCFoundationAPI.cpp lib/Frontend/Rewrite/RewriteModernObjC.cpp lib/Index/IndexDecl.cpp lib/Sema/SemaCodeComplete.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclObjC.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprMember.cpp lib/Sema/SemaExprObjC.cpp lib/Sema/SemaLookup.cpp lib/Sema/SemaObjCProperty.cpp lib/Sema/SemaPseudoObject.cpp lib/Sema/SemaStmt.cpp lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp lib/StaticAnalyzer/Core/CallEvent.cpp test/Modules/interface-visibility.m
Index: test/Modules/interface-visibility.m =================================================================== --- test/Modules/interface-visibility.m +++ test/Modules/interface-visibility.m @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -fmodules -fobjc-arc -x objective-c-module-map %s -fmodule-name=Foo -verify + +module Foo {} + +#pragma clang module contents +#pragma clang module begin Foo + +// expected-no-diagnostics + +#pragma clang module build Foundation +module Foundation {} +#pragma clang module contents +#pragma clang module begin Foundation +@interface NSIndexSet +@end +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module import Foundation + +@interface NSIndexSet (Testing) +- (int)foo; +@end + +static inline int test(NSIndexSet *obj) { + return [obj foo]; +} + +#pragma clang module end Index: lib/StaticAnalyzer/Core/CallEvent.cpp =================================================================== --- lib/StaticAnalyzer/Core/CallEvent.cpp +++ lib/StaticAnalyzer/Core/CallEvent.cpp @@ -872,7 +872,7 @@ // the selector. ObjCMethodDecl *D = nullptr; while (true) { - D = IDecl->lookupMethod(Sel, true); + D = IDecl->lookupMethod(Sel, true, AllDeclsVisible); // Cannot find a public definition. if (!D) @@ -1026,7 +1026,7 @@ // Query lookupPrivateMethod() if the cache does not hit. if (!Val.hasValue()) { - Val = IDecl->lookupPrivateMethod(Sel); + Val = IDecl->lookupPrivateMethod(Sel, AllDeclsVisible); // If the method is a property accessor, we should try to "inline" it // even if we don't actually have an implementation. @@ -1048,13 +1048,14 @@ auto *ID = CompileTimeMD->getClassInterface(); for (auto *CatDecl : ID->visible_extensions()) { Val = CatDecl->getMethod(Sel, - CompileTimeMD->isInstanceMethod()); + CompileTimeMD->isInstanceMethod(), + AllDeclsVisible); if (*Val) break; } } if (!*Val) - Val = IDecl->lookupInstanceMethod(Sel); + Val = IDecl->lookupInstanceMethod(Sel, AllDeclsVisible); } } @@ -1071,7 +1072,8 @@ // class name. if (ObjCInterfaceDecl *IDecl = E->getReceiverInterface()) { // Find/Return the method implementation. - return RuntimeDefinition(IDecl->lookupPrivateClassMethod(Sel)); + return RuntimeDefinition( + IDecl->lookupPrivateClassMethod(Sel, AllDeclsVisible)); } } Index: lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp @@ -1533,7 +1533,7 @@ Selector S = Msg.getSelector(); const ObjCMethodDecl *Method = Msg.getDecl(); if (!Method && ReceiverClass) - Method = ReceiverClass->getInstanceMethod(S); + Method = ReceiverClass->getInstanceMethod(S, AllDeclsVisible); return getMethodSummary(S, ReceiverClass, Method, Msg.getResultType(), ObjCMethodSummaries); Index: lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp +++ lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp @@ -62,7 +62,7 @@ ImplD = CatD->getClassInterface()->getImplementation(); } - if (!ImplD || ImplD->HasUserDeclaredSetterMethod(D)) + if (!ImplD || ImplD->HasUserDeclaredSetterMethod(D, AllDeclsVisible)) return; SmallString<128> Str; Index: lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp +++ lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp @@ -430,8 +430,8 @@ const ObjCMethodDecl *InterfD = *I; // Get the corresponding method in the @implementation. - const ObjCMethodDecl *D = ImplD->getMethod(InterfD->getSelector(), - InterfD->isInstanceMethod()); + const ObjCMethodDecl *D = ImplD->getMethod( + InterfD->getSelector(), InterfD->isInstanceMethod(), AllDeclsVisible); if (D && D->hasBody()) { AtImplementationContainsAtLeastOnePartialInvalidationMethod = true; @@ -482,8 +482,8 @@ const ObjCMethodDecl *InterfD = *I; // Get the corresponding method in the @implementation. - const ObjCMethodDecl *D = ImplD->getMethod(InterfD->getSelector(), - InterfD->isInstanceMethod()); + const ObjCMethodDecl *D = ImplD->getMethod( + InterfD->getSelector(), InterfD->isInstanceMethod(), AllDeclsVisible); if (D && D->hasBody()) { AtImplementationContainsAtLeastOneInvalidationMethod = true; Index: lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp +++ lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp @@ -668,9 +668,9 @@ const ObjCInterfaceDecl *InterfaceDecl = TrackedType->getInterfaceDecl(); // The method might not be found. Selector Sel = MessageExpr->getSelector(); - Method = InterfaceDecl->lookupInstanceMethod(Sel); + Method = InterfaceDecl->lookupInstanceMethod(Sel, AllDeclsVisible); if (!Method) - Method = InterfaceDecl->lookupClassMethod(Sel); + Method = InterfaceDecl->lookupClassMethod(Sel, AllDeclsVisible); } } Index: lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp +++ lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp @@ -186,9 +186,9 @@ return; ObjCMethodDecl *GetterMethod = - InterfD->getInstanceMethod(PD->getGetterName()); + InterfD->getInstanceMethod(PD->getGetterName(), AllDeclsVisible); ObjCMethodDecl *SetterMethod = - InterfD->getInstanceMethod(PD->getSetterName()); + InterfD->getInstanceMethod(PD->getSetterName(), AllDeclsVisible); if (SetterMethod && SetterMethod->getCanonicalDecl() == MD) return; Index: lib/Sema/SemaStmt.cpp =================================================================== --- lib/Sema/SemaStmt.cpp +++ lib/Sema/SemaStmt.cpp @@ -1750,8 +1750,9 @@ // If there's an interface, look in both the public and private APIs. if (iface) { - method = iface->lookupInstanceMethod(selector); - if (!method) method = iface->lookupPrivateMethod(selector); + method = iface->lookupInstanceMethod(selector, IsHiddenCallback(*this)); + if (!method) + method = iface->lookupPrivateMethod(selector, IsHiddenCallback(*this)); } // Also check protocol qualifiers. Index: lib/Sema/SemaPseudoObject.cpp =================================================================== --- lib/Sema/SemaPseudoObject.cpp +++ lib/Sema/SemaPseudoObject.cpp @@ -660,7 +660,7 @@ PropertyName[0] = front; IdentifierInfo *AltMember = &S.PP.getIdentifierTable().get(PropertyName); if (ObjCPropertyDecl *prop1 = IFace->FindPropertyDeclaration( - AltMember, prop->getQueryKind())) + AltMember, prop->getQueryKind(), Sema::IsHiddenCallback(S))) if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) { S.Diag(RefExpr->getExprLoc(), diag::err_property_setter_ambiguous_use) << prop << prop1 << setter->getSelector(); Index: lib/Sema/SemaObjCProperty.cpp =================================================================== --- lib/Sema/SemaObjCProperty.cpp +++ lib/Sema/SemaObjCProperty.cpp @@ -443,7 +443,8 @@ // Find the property in the extended class's primary class or // extensions. ObjCPropertyDecl *PIDecl = CCPrimary->FindPropertyVisibleInPrimaryClass( - PropertyId, ObjCPropertyDecl::getQueryKind(isClassProperty)); + PropertyId, ObjCPropertyDecl::getQueryKind(isClassProperty), + IsHiddenCallback(*this)); // If we found a property in an extension, complain. if (PIDecl && isa<ObjCCategoryDecl>(PIDecl->getDeclContext())) { @@ -628,7 +629,8 @@ (Attributes & ObjCDeclSpec::DQ_PR_class); // Class property and instance property can have the same name. if (ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl( - DC, PropertyId, ObjCPropertyDecl::getQueryKind(isClassProperty))) { + DC, PropertyId, ObjCPropertyDecl::getQueryKind(isClassProperty), + IsHiddenCallback(*this))) { Diag(PDecl->getLocation(), diag::err_duplicate_property); Diag(prevDecl->getLocation(), diag::note_property_declare); PDecl->setInvalidDecl(); @@ -864,7 +866,7 @@ } /// Determine whether any storage attributes were written on the property. -static bool hasWrittenStorageAttribute(ObjCPropertyDecl *Prop, +static bool hasWrittenStorageAttribute(Sema &S, ObjCPropertyDecl *Prop, ObjCPropertyQueryKind QueryKind) { if (Prop->getPropertyAttributesAsWritten() & OwnershipMask) return true; @@ -889,7 +891,7 @@ // Look through all of the protocols. for (const auto *Proto : OrigClass->all_referenced_protocols()) { if (ObjCPropertyDecl *OrigProp = Proto->FindPropertyDeclaration( - Prop->getIdentifier(), QueryKind)) + Prop->getIdentifier(), QueryKind, Sema::IsHiddenCallback(S))) return OrigProp->getPropertyAttributesAsWritten() & OwnershipMask; } @@ -934,7 +936,8 @@ "ActOnPropertyImplDecl - @implementation without @interface"); // Look for this property declaration in the @implementation's @interface - property = IDecl->FindPropertyDeclaration(PropertyId, QueryKind); + property = IDecl->FindPropertyDeclaration(PropertyId, QueryKind, + IsHiddenCallback(*this)); if (!property) { Diag(PropertyLoc, diag::err_bad_property_decl) << IDecl->getDeclName(); return nullptr; @@ -1016,7 +1019,8 @@ if (!Category) return nullptr; // Look for this property declaration in @implementation's category - property = Category->FindPropertyDeclaration(PropertyId, QueryKind); + property = Category->FindPropertyDeclaration(PropertyId, QueryKind, + IsHiddenCallback(*this)); if (!property) { Diag(PropertyLoc, diag::err_bad_category_property_decl) << Category->getDeclName(); @@ -1128,7 +1132,7 @@ // It's an error if we have to do this and the user didn't // explicitly write an ownership attribute on the property. - if (!hasWrittenStorageAttribute(property, QueryKind) && + if (!hasWrittenStorageAttribute(*this, property, QueryKind) && !(kind & ObjCPropertyDecl::OBJC_PR_strong)) { Diag(PropertyDiagLoc, diag::err_arc_objc_property_default_assign_on_object); @@ -1629,8 +1633,9 @@ ObjCMethodDecl *Method, ObjCIvarDecl *IV) { if (!IV->getSynthesize()) return false; - ObjCMethodDecl *IMD = IFace->lookupMethod(Method->getSelector(), - Method->isInstanceMethod()); + ObjCMethodDecl *IMD = + IFace->lookupMethod(Method->getSelector(), Method->isInstanceMethod(), + IsHiddenCallback(*this)); if (!IMD || !IMD->isPropertyAccessor()) return false; @@ -1653,7 +1658,7 @@ return false; } -static bool SuperClassImplementsProperty(ObjCInterfaceDecl *IDecl, +static bool SuperClassImplementsProperty(Sema &S, ObjCInterfaceDecl *IDecl, ObjCPropertyDecl *Prop) { bool SuperClassImplementsGetter = false; bool SuperClassImplementsSetter = false; @@ -1662,10 +1667,14 @@ while (IDecl->getSuperClass()) { ObjCInterfaceDecl *SDecl = IDecl->getSuperClass(); - if (!SuperClassImplementsGetter && SDecl->getInstanceMethod(Prop->getGetterName())) + if (!SuperClassImplementsGetter && + SDecl->getInstanceMethod(Prop->getGetterName(), + Sema::IsHiddenCallback(S))) SuperClassImplementsGetter = true; - if (!SuperClassImplementsSetter && SDecl->getInstanceMethod(Prop->getSetterName())) + if (!SuperClassImplementsSetter && + SDecl->getInstanceMethod(Prop->getSetterName(), + Sema::IsHiddenCallback(S))) SuperClassImplementsSetter = true; if (SuperClassImplementsGetter && SuperClassImplementsSetter) return true; @@ -1697,10 +1706,12 @@ if (IMPDecl->FindPropertyImplDecl( Prop->getIdentifier(), Prop->getQueryKind())) continue; - if (IMPDecl->getInstanceMethod(Prop->getGetterName())) { + if (IMPDecl->getInstanceMethod(Prop->getGetterName(), + IsHiddenCallback(*this))) { if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly) continue; - if (IMPDecl->getInstanceMethod(Prop->getSetterName())) + if (IMPDecl->getInstanceMethod(Prop->getSetterName(), + IsHiddenCallback(*this))) continue; } if (ObjCPropertyImplDecl *PID = @@ -1720,7 +1731,8 @@ // Suppress the warning if class's superclass implements property's // getter and implements property's setter (if readwrite property). // Or, if property is going to be implemented in its super class. - if (!SuperClassImplementsProperty(IDecl, Prop) && !PropInSuperClass) { + if (!SuperClassImplementsProperty(*this, IDecl, Prop) && + !PropInSuperClass) { Diag(IMPDecl->getLocation(), diag::warn_auto_synthesizing_protocol_property) << Prop << Proto; @@ -1730,11 +1742,13 @@ } // If property to be implemented in the super class, ignore. if (PropInSuperClass) { - if ((Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readwrite) && + if ((Prop->getPropertyAttributes() & + ObjCPropertyDecl::OBJC_PR_readwrite) && (PropInSuperClass->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly) && - !IMPDecl->getInstanceMethod(Prop->getSetterName()) && - !IDecl->HasUserDeclaredSetterMethod(Prop)) { + !IMPDecl->getInstanceMethod(Prop->getSetterName(), + IsHiddenCallback(*this)) && + !IDecl->HasUserDeclaredSetterMethod(Prop, IsHiddenCallback(*this))) { Diag(Prop->getLocation(), diag::warn_no_autosynthesis_property) << Prop->getIdentifier(); Diag(PropInSuperClass->getLocation(), diag::note_property_declare); @@ -1793,8 +1807,8 @@ // the class is going to implement them. if (I == SMap.end() && (PrimaryClass == nullptr || - !PrimaryClass->lookupPropertyAccessor(Method, C, - Prop->isClassProperty()))) { + !PrimaryClass->lookupPropertyAccessor(Method, Sema::IsHiddenCallback(S), + C, Prop->isClassProperty()))) { unsigned diag = isa<ObjCCategoryDecl>(CDecl) ? (Prop->isClassProperty() @@ -1935,8 +1949,10 @@ property->getSetterMethodDecl()) { auto *getterMethod = property->getGetterMethodDecl(); auto *setterMethod = property->getSetterMethodDecl(); - if (!impDecl->getInstanceMethod(setterMethod->getSelector()) && - !impDecl->getInstanceMethod(getterMethod->getSelector())) { + if (!impDecl->getInstanceMethod(setterMethod->getSelector(), + IsHiddenCallback(*this)) && + !impDecl->getInstanceMethod(getterMethod->getSelector(), + IsHiddenCallback(*this))) { SourceLocation loc = propertyImpl->getLocation(); if (loc.isInvalid()) loc = impDecl->getLocStart(); @@ -1973,12 +1989,12 @@ if (!(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_atomic) && !(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_nonatomic)) { - GetterMethod = Property->isClassProperty() ? - IMPDecl->getClassMethod(Property->getGetterName()) : - IMPDecl->getInstanceMethod(Property->getGetterName()); - SetterMethod = Property->isClassProperty() ? - IMPDecl->getClassMethod(Property->getSetterName()) : - IMPDecl->getInstanceMethod(Property->getSetterName()); + GetterMethod = IMPDecl->getMethod(Property->getGetterName(), + !Property->isClassProperty(), + IsHiddenCallback(*this)); + SetterMethod = IMPDecl->getMethod(Property->getSetterName(), + !Property->isClassProperty(), + IsHiddenCallback(*this)); LookedUpGetterSetter = true; if (GetterMethod) { Diag(GetterMethod->getLocation(), @@ -2003,12 +2019,12 @@ if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) continue; if (!LookedUpGetterSetter) { - GetterMethod = Property->isClassProperty() ? - IMPDecl->getClassMethod(Property->getGetterName()) : - IMPDecl->getInstanceMethod(Property->getGetterName()); - SetterMethod = Property->isClassProperty() ? - IMPDecl->getClassMethod(Property->getSetterName()) : - IMPDecl->getInstanceMethod(Property->getSetterName()); + GetterMethod = IMPDecl->getMethod(Property->getGetterName(), + !Property->isClassProperty(), + IsHiddenCallback(*this)); + SetterMethod = IMPDecl->getMethod(Property->getSetterName(), + !Property->isClassProperty(), + IsHiddenCallback(*this)); } if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) { SourceLocation MethodLoc = @@ -2052,7 +2068,7 @@ const ObjCPropertyDecl *PD = PID->getPropertyDecl(); if (PD && !PD->hasAttr<NSReturnsNotRetainedAttr>() && !PD->isClassProperty() && - !D->getInstanceMethod(PD->getGetterName())) { + !D->getInstanceMethod(PD->getGetterName(), IsHiddenCallback(*this))) { ObjCMethodDecl *method = PD->getGetterMethodDecl(); if (!method) continue; @@ -2121,7 +2137,8 @@ const ObjCMethodDecl *MD = *I; if (!InitSelSet.count(MD->getSelector())) { bool Ignore = false; - if (auto *IMD = IFD->getInstanceMethod(MD->getSelector())) { + if (auto *IMD = IFD->getInstanceMethod(MD->getSelector(), + IsHiddenCallback(*this))) { Ignore = IMD->isUnavailable(); } if (!Ignore) { @@ -2158,9 +2175,8 @@ return; bool IsClassProperty = property->isClassProperty(); - GetterMethod = IsClassProperty ? - CD->getClassMethod(property->getGetterName()) : - CD->getInstanceMethod(property->getGetterName()); + GetterMethod = CD->getMethod(property->getGetterName(), !IsClassProperty, + IsHiddenCallback(*this)); // if setter or getter is not found in class extension, it might be // in the primary class. @@ -2167,21 +2183,18 @@ if (!GetterMethod) if (const ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CD)) if (CatDecl->IsClassExtension()) - GetterMethod = IsClassProperty ? CatDecl->getClassInterface()-> - getClassMethod(property->getGetterName()) : - CatDecl->getClassInterface()-> - getInstanceMethod(property->getGetterName()); - - SetterMethod = IsClassProperty ? - CD->getClassMethod(property->getSetterName()) : - CD->getInstanceMethod(property->getSetterName()); + GetterMethod = CatDecl->getClassInterface()->getMethod( + property->getGetterName(), !IsClassProperty, + IsHiddenCallback(*this)); + + SetterMethod = CD->getMethod(property->getSetterName(), !IsClassProperty, + IsHiddenCallback(*this)); if (!SetterMethod) if (const ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CD)) if (CatDecl->IsClassExtension()) - SetterMethod = IsClassProperty ? CatDecl->getClassInterface()-> - getClassMethod(property->getSetterName()) : - CatDecl->getClassInterface()-> - getInstanceMethod(property->getSetterName()); + SetterMethod = CatDecl->getClassInterface()->getMethod( + property->getSetterName(), !IsClassProperty, + IsHiddenCallback(*this)); DiagnosePropertyAccessorMismatch(property, GetterMethod, property->getLocation()); Index: lib/Sema/SemaLookup.cpp =================================================================== --- lib/Sema/SemaLookup.cpp +++ lib/Sema/SemaLookup.cpp @@ -4261,7 +4261,8 @@ } if (ObjCPropertyDecl *Prop = Class->FindPropertyDeclaration( - Name, ObjCPropertyQueryKind::OBJC_PR_query_instance)) { + Name, ObjCPropertyQueryKind::OBJC_PR_query_instance, + Sema::IsHiddenCallback(SemaRef))) { Res.addDecl(Prop); Res.resolveKind(); return; Index: lib/Sema/SemaExprObjC.cpp =================================================================== --- lib/Sema/SemaExprObjC.cpp +++ lib/Sema/SemaExprObjC.cpp @@ -279,7 +279,8 @@ } // Look for the appropriate method within NSNumber. - ObjCMethodDecl *Method = S.NSNumberDecl->lookupClassMethod(Sel); + ObjCMethodDecl *Method = + S.NSNumberDecl->lookupClassMethod(Sel, Sema::IsHiddenCallback(S)); if (!Method && S.getLangOpts().DebuggerObjCLiteral) { // create a stub definition this NSNumber factory method. TypeSourceInfo *ReturnTInfo = nullptr; @@ -531,7 +532,8 @@ Selector stringWithUTF8String = Context.Selectors.getUnarySelector(II); // Look for the appropriate method within NSString. - BoxingMethod = NSStringDecl->lookupClassMethod(stringWithUTF8String); + BoxingMethod = NSStringDecl->lookupClassMethod( + stringWithUTF8String, Sema::IsHiddenCallback(*this)); if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) { // Debugger needs to work even if NSString hasn't been defined. TypeSourceInfo *ReturnTInfo = nullptr; @@ -636,7 +638,8 @@ Selector ValueWithBytesObjCType = Context.Selectors.getSelector(2, II); // Look for the appropriate method within NSValue. - BoxingMethod = NSValueDecl->lookupClassMethod(ValueWithBytesObjCType); + BoxingMethod = NSValueDecl->lookupClassMethod(ValueWithBytesObjCType, + IsHiddenCallback(*this)); if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) { // Debugger needs to work even if NSValue hasn't been defined. TypeSourceInfo *ReturnTInfo = nullptr; @@ -778,7 +781,8 @@ if (!ArrayWithObjectsMethod) { Selector Sel = NSAPIObj->getNSArraySelector(NSAPI::NSArr_arrayWithObjectsCount); - ObjCMethodDecl *Method = NSArrayDecl->lookupClassMethod(Sel); + ObjCMethodDecl *Method = + NSArrayDecl->lookupClassMethod(Sel, IsHiddenCallback(*this)); if (!Method && getLangOpts().DebuggerObjCLiteral) { TypeSourceInfo *ReturnTInfo = nullptr; Method = ObjCMethodDecl::Create( @@ -884,7 +888,8 @@ if (!DictionaryWithObjectsMethod) { Selector Sel = NSAPIObj->getNSDictionarySelector( NSAPI::NSDict_dictionaryWithObjectsForKeysCount); - ObjCMethodDecl *Method = NSDictionaryDecl->lookupClassMethod(Sel); + ObjCMethodDecl *Method = + NSDictionaryDecl->lookupClassMethod(Sel, IsHiddenCallback(*this)); if (!Method && getLangOpts().DebuggerObjCLiteral) { Method = ObjCMethodDecl::Create(Context, SourceLocation(), SourceLocation(), Sel, @@ -1402,7 +1407,7 @@ /// Look for an ObjC method whose result type exactly matches the given type. static const ObjCMethodDecl * -findExplicitInstancetypeDeclarer(const ObjCMethodDecl *MD, +findExplicitInstancetypeDeclarer(Sema &S, const ObjCMethodDecl *MD, QualType instancetype) { if (MD->getReturnType() == instancetype) return MD; @@ -1419,9 +1424,10 @@ iface = impl->getClassInterface(); } - const ObjCMethodDecl *ifaceMD = - iface->getMethod(MD->getSelector(), MD->isInstanceMethod()); - if (ifaceMD) return findExplicitInstancetypeDeclarer(ifaceMD, instancetype); + const ObjCMethodDecl *ifaceMD = iface->getMethod( + MD->getSelector(), MD->isInstanceMethod(), Sema::IsHiddenCallback(S)); + if (ifaceMD) + return findExplicitInstancetypeDeclarer(S, ifaceMD, instancetype); } SmallVector<const ObjCMethodDecl *, 4> overrides; @@ -1428,7 +1434,7 @@ MD->getOverriddenMethods(overrides); for (unsigned i = 0, e = overrides.size(); i != e; ++i) { if (const ObjCMethodDecl *result = - findExplicitInstancetypeDeclarer(overrides[i], instancetype)) + findExplicitInstancetypeDeclarer(S, overrides[i], instancetype)) return result; } @@ -1445,8 +1451,8 @@ // Look for a method overridden by this method which explicitly uses // 'instancetype'. - if (const ObjCMethodDecl *overridden = - findExplicitInstancetypeDeclarer(MD, Context.getObjCInstanceType())) { + if (const ObjCMethodDecl *overridden = findExplicitInstancetypeDeclarer( + *this, MD, Context.getObjCInstanceType())) { SourceRange range = overridden->getReturnTypeSourceRange(); SourceLocation loc = range.getBegin(); if (loc.isInvalid()) @@ -1556,7 +1562,7 @@ ReceiverType->getAs<ObjCObjectPointerType>()->getInterfaceDecl()) { Diag(ThisClass->getLocation(), diag::note_receiver_class_declared); if (!RecRange.isInvalid()) - if (ThisClass->lookupClassMethod(Sel)) + if (ThisClass->lookupClassMethod(Sel, IsHiddenCallback(*this))) Diag(RecRange.getBegin(),diag::note_receiver_expr_here) << FixItHint::CreateReplacement(RecRange, ThisClass->getNameAsString()); @@ -1717,18 +1723,21 @@ const ObjCObjectType *objType = type->castAs<ObjCObjectType>(); if (ObjCInterfaceDecl *iface = objType->getInterface()) { // Look it up in the main interface (and categories, etc.) - if (ObjCMethodDecl *method = iface->lookupMethod(sel, isInstance)) + if (ObjCMethodDecl *method = + iface->lookupMethod(sel, isInstance, IsHiddenCallback(*this))) return method; // Okay, look for "private" methods declared in any // @implementations we've seen. - if (ObjCMethodDecl *method = iface->lookupPrivateMethod(sel, isInstance)) + if (ObjCMethodDecl *method = iface->lookupPrivateMethod( + sel, isInstance, IsHiddenCallback(*this))) return method; } // Check qualifiers. for (const auto *I : objType->quals()) - if (ObjCMethodDecl *method = I->lookupMethod(sel, isInstance)) + if (ObjCMethodDecl *method = + I->lookupMethod(sel, isInstance, IsHiddenCallback(*this))) return method; return nullptr; @@ -1742,7 +1751,7 @@ { ObjCMethodDecl *MD = nullptr; for (const auto *PROTO : OPT->quals()) { - if ((MD = PROTO->lookupMethod(Sel, Instance))) { + if ((MD = PROTO->lookupMethod(Sel, Instance, IsHiddenCallback(*this)))) { return MD; } } @@ -1775,9 +1784,10 @@ diag::err_property_not_found_forward_class, MemberName, BaseRange)) return ExprError(); - + if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration( - Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) { + Member, ObjCPropertyQueryKind::OBJC_PR_query_instance, + IsHiddenCallback(*this))) { // Check whether we can reference this property. if (DiagnoseUseOfDecl(PD, MemberLoc)) return ExprError(); @@ -1793,7 +1803,8 @@ // Check protocols on qualified interfaces. for (const auto *I : OPT->quals()) if (ObjCPropertyDecl *PD = I->FindPropertyDeclaration( - Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) { + Member, ObjCPropertyQueryKind::OBJC_PR_query_instance, + IsHiddenCallback(*this))) { // Check whether we can reference this property. if (DiagnoseUseOfDecl(PD, MemberLoc)) return ExprError(); @@ -1814,8 +1825,9 @@ // shared with the code in ActOnInstanceMessage. Selector Sel = PP.getSelectorTable().getNullarySelector(Member); - ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel); - + ObjCMethodDecl *Getter = + IFace->lookupInstanceMethod(Sel, IsHiddenCallback(*this)); + // May be found in property's qualified list. if (!Getter) Getter = LookupMethodInQualifiedType(Sel, OPT, true); @@ -1822,7 +1834,7 @@ // If this reference is in an @implementation, check for 'private' methods. if (!Getter) - Getter = IFace->lookupPrivateMethod(Sel); + Getter = IFace->lookupPrivateMethod(Sel, IsHiddenCallback(*this)); if (Getter) { // Check if we can reference this property. @@ -1834,8 +1846,9 @@ Selector SetterSel = SelectorTable::constructSetterSelector(PP.getIdentifierTable(), PP.getSelectorTable(), Member); - ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel); - + ObjCMethodDecl *Setter = + IFace->lookupInstanceMethod(SetterSel, IsHiddenCallback(*this)); + // May be found in property's qualified list. if (!Setter) Setter = LookupMethodInQualifiedType(SetterSel, OPT, true); @@ -1843,7 +1856,7 @@ if (!Setter) { // If this reference is in an @implementation, also check for 'private' // methods. - Setter = IFace->lookupPrivateMethod(SetterSel); + Setter = IFace->lookupPrivateMethod(SetterSel, IsHiddenCallback(*this)); } if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc)) @@ -1854,16 +1867,16 @@ // name 'x'. if (Setter && Setter->isImplicit() && Setter->isPropertyAccessor() && !IFace->FindPropertyDeclaration( - Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) { - if (const ObjCPropertyDecl *PDecl = Setter->findPropertyDecl()) { - // Do not warn if user is using property-dot syntax to make call to - // user named setter. - if (!(PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter)) - Diag(MemberLoc, - diag::warn_property_access_suggest) - << MemberName << QualType(OPT, 0) << PDecl->getName() - << FixItHint::CreateReplacement(MemberLoc, PDecl->getName()); - } + Member, ObjCPropertyQueryKind::OBJC_PR_query_instance, + IsHiddenCallback(*this))) { + if (const ObjCPropertyDecl *PDecl = Setter->findPropertyDecl()) { + // Do not warn if user is using property-dot syntax to make call to + // user named setter. + if (!(PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter)) + Diag(MemberLoc, diag::warn_property_access_suggest) + << MemberName << QualType(OPT, 0) << PDecl->getName() + << FixItHint::CreateReplacement(MemberLoc, PDecl->getName()); + } } if (Getter || Setter) { @@ -1986,7 +1999,8 @@ Selector GetterSel; Selector SetterSel; if (auto PD = IFace->FindPropertyDeclaration( - &propertyName, ObjCPropertyQueryKind::OBJC_PR_query_class)) { + &propertyName, ObjCPropertyQueryKind::OBJC_PR_query_class, + IsHiddenCallback(*this))) { GetterSel = PD->getGetterName(); SetterSel = PD->getSetterName(); } else { @@ -1996,11 +2010,13 @@ } // Search for a declared property first. - ObjCMethodDecl *Getter = IFace->lookupClassMethod(GetterSel); + ObjCMethodDecl *Getter = + IFace->lookupClassMethod(GetterSel, IsHiddenCallback(*this)); // If this reference is in an @implementation, check for 'private' methods. if (!Getter) - Getter = IFace->lookupPrivateClassMethod(GetterSel); + Getter = + IFace->lookupPrivateClassMethod(GetterSel, IsHiddenCallback(*this)); if (Getter) { // FIXME: refactor/share with ActOnMemberReference(). @@ -2010,15 +2026,17 @@ } // Look for the matching setter, in case it is needed. - ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel); + ObjCMethodDecl *Setter = + IFace->lookupClassMethod(SetterSel, IsHiddenCallback(*this)); if (!Setter) { // If this reference is in an @implementation, also check for 'private' // methods. - Setter = IFace->lookupPrivateClassMethod(SetterSel); + Setter = + IFace->lookupPrivateClassMethod(SetterSel, IsHiddenCallback(*this)); } // Look through local category implementations associated with the class. if (!Setter) - Setter = IFace->getCategoryClassMethod(SetterSel); + Setter = IFace->getCategoryClassMethod(SetterSel, IsHiddenCallback(*this)); if (Setter && DiagnoseUseOfDecl(Setter, propertyNameLoc)) return ExprError(); @@ -2282,19 +2300,20 @@ const auto *OPT = ReceiverType->getAs<ObjCObjectPointerType>(); if (!OPT || !OPT->getInterfaceDecl()) return; - ImpliedMethod = - OPT->getInterfaceDecl()->lookupInstanceMethod(SE->getSelector()); + ImpliedMethod = OPT->getInterfaceDecl()->lookupInstanceMethod( + SE->getSelector(), Sema::IsHiddenCallback(S)); if (!ImpliedMethod) - ImpliedMethod = - OPT->getInterfaceDecl()->lookupPrivateMethod(SE->getSelector()); + ImpliedMethod = OPT->getInterfaceDecl()->lookupPrivateMethod( + SE->getSelector(), Sema::IsHiddenCallback(S)); } else { const auto *IT = ReceiverType->getAs<ObjCInterfaceType>(); if (!IT) return; - ImpliedMethod = IT->getDecl()->lookupClassMethod(SE->getSelector()); + ImpliedMethod = IT->getDecl()->lookupClassMethod(SE->getSelector(), + Sema::IsHiddenCallback(S)); if (!ImpliedMethod) - ImpliedMethod = - IT->getDecl()->lookupPrivateClassMethod(SE->getSelector()); + ImpliedMethod = IT->getDecl()->lookupPrivateClassMethod( + SE->getSelector(), Sema::IsHiddenCallback(S)); } if (!ImpliedMethod) return; @@ -2444,11 +2463,11 @@ << Method->getDeclName(); } if (!Method) - Method = Class->lookupClassMethod(Sel); + Method = Class->lookupClassMethod(Sel, IsHiddenCallback(*this)); // If we have an implementation in scope, check "private" methods. if (!Method) - Method = Class->lookupPrivateClassMethod(Sel); + Method = Class->lookupPrivateClassMethod(Sel, IsHiddenCallback(*this)); if (Method && DiagnoseUseOfDecl(Method, SelLoc)) return ExprError(); @@ -2760,10 +2779,12 @@ if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) { if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) { // First check the public methods in the class interface. - Method = ClassDecl->lookupClassMethod(Sel); + Method = + ClassDecl->lookupClassMethod(Sel, IsHiddenCallback(*this)); if (!Method) - Method = ClassDecl->lookupPrivateClassMethod(Sel); + Method = ClassDecl->lookupPrivateClassMethod( + Sel, IsHiddenCallback(*this)); } if (Method && DiagnoseUseOfDecl(Method, SelLoc)) return ExprError(); @@ -2838,7 +2859,8 @@ : SuperLoc, diag::note_receiver_is_id); Method = nullptr; } else { - Method = ClassDecl->lookupInstanceMethod(Sel); + Method = + ClassDecl->lookupInstanceMethod(Sel, IsHiddenCallback(*this)); } if (!Method) @@ -2847,7 +2869,7 @@ if (!Method) { // If we have implementations in scope, check "private" methods. - Method = ClassDecl->lookupPrivateMethod(Sel); + Method = ClassDecl->lookupPrivateMethod(Sel, IsHiddenCallback(*this)); if (!Method && getLangOpts().ObjCAutoRefCount) { Diag(SelLoc, diag::err_arc_may_not_respond) @@ -2913,7 +2935,7 @@ // Either we know this is a designated initializer or we // conservatively assume it because we don't know for sure. if (!ID->declaresOrInheritsDesignatedInitializers() || - ID->isDesignatedInitializer(Sel)) { + ID->isDesignatedInitializer(Sel, IsHiddenCallback(*this))) { isDesignatedInitChain = true; DIFunctionScopeInfo->ObjCWarnForNoDesignatedInitChain = false; } @@ -2923,7 +2945,8 @@ if (!isDesignatedInitChain) { const ObjCMethodDecl *InitMethod = nullptr; bool isDesignated = - getCurMethodDecl()->isDesignatedInitializerForTheInterface(&InitMethod); + getCurMethodDecl()->isDesignatedInitializerForTheInterface( + IsHiddenCallback(*this), &InitMethod); assert(isDesignated && InitMethod); (void)isDesignated; Diag(SelLoc, SuperLoc.isValid() ? @@ -3986,7 +4009,8 @@ // Check for an existing class method with the given selector name. if (CfToNs && CMId) { Selector Sel = Context.Selectors.getUnarySelector(CMId); - ClassMethod = RelatedClass->lookupMethod(Sel, false); + ClassMethod = + RelatedClass->lookupMethod(Sel, false, IsHiddenCallback(*this)); if (!ClassMethod) { if (Diagnose) { Diag(Loc, diag::err_objc_bridged_related_known_method) @@ -4000,7 +4024,8 @@ // Check for an existing instance method with the given selector name. if (!CfToNs && IMId) { Selector Sel = Context.Selectors.getNullarySelector(IMId); - InstanceMethod = RelatedClass->lookupMethod(Sel, true); + InstanceMethod = + RelatedClass->lookupMethod(Sel, true, IsHiddenCallback(*this)); if (!InstanceMethod) { if (Diagnose) { Diag(Loc, diag::err_objc_bridged_related_known_method) Index: lib/Sema/SemaExprMember.cpp =================================================================== --- lib/Sema/SemaExprMember.cpp +++ lib/Sema/SemaExprMember.cpp @@ -426,20 +426,21 @@ return VT; // should never get here (a typedef type should always be found). } -static Decl *FindGetterSetterNameDeclFromProtocolList(const ObjCProtocolDecl*PDecl, - IdentifierInfo *Member, - const Selector &Sel, - ASTContext &Context) { +static Decl * +FindGetterSetterNameDeclFromProtocolList(const ObjCProtocolDecl *PDecl, + IdentifierInfo *Member, + const Selector &Sel, Sema &S) { if (Member) if (ObjCPropertyDecl *PD = PDecl->FindPropertyDeclaration( - Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) + Member, ObjCPropertyQueryKind::OBJC_PR_query_instance, + Sema::IsHiddenCallback(S))) return PD; - if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Sel)) + if (ObjCMethodDecl *OMD = + PDecl->getInstanceMethod(Sel, Sema::IsHiddenCallback(S))) return OMD; for (const auto *I : PDecl->protocols()) { - if (Decl *D = FindGetterSetterNameDeclFromProtocolList(I, Member, Sel, - Context)) + if (Decl *D = FindGetterSetterNameDeclFromProtocolList(I, Member, Sel, S)) return D; } return nullptr; @@ -448,18 +449,20 @@ static Decl *FindGetterSetterNameDecl(const ObjCObjectPointerType *QIdTy, IdentifierInfo *Member, const Selector &Sel, - ASTContext &Context) { + Sema &S) { // Check protocols on qualified interfaces. Decl *GDecl = nullptr; for (const auto *I : QIdTy->quals()) { if (Member) if (ObjCPropertyDecl *PD = I->FindPropertyDeclaration( - Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) { + Member, ObjCPropertyQueryKind::OBJC_PR_query_instance, + Sema::IsHiddenCallback(S))) { GDecl = PD; break; } // Also must look for a getter or setter name which uses property syntax. - if (ObjCMethodDecl *OMD = I->getInstanceMethod(Sel)) { + if (ObjCMethodDecl *OMD = + I->getInstanceMethod(Sel, Sema::IsHiddenCallback(S))) { GDecl = OMD; break; } @@ -467,7 +470,7 @@ if (!GDecl) { for (const auto *I : QIdTy->quals()) { // Search in the protocol-qualifier list of current protocol. - GDecl = FindGetterSetterNameDeclFromProtocolList(I, Member, Sel, Context); + GDecl = FindGetterSetterNameDeclFromProtocolList(I, Member, Sel, S); if (GDecl) return GDecl; } @@ -1439,7 +1442,8 @@ } else { if (IsArrow && IDecl->FindPropertyDeclaration( - Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) { + Member, ObjCPropertyQueryKind::OBJC_PR_query_instance, + Sema::IsHiddenCallback(S))) { S.Diag(MemberLoc, diag::err_property_found_suggest) << Member << BaseExpr.get()->getType() << FixItHint::CreateReplacement(OpLoc, "."); @@ -1557,7 +1561,7 @@ // Check protocols on qualified interfaces. Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member); if (Decl *PMDecl = - FindGetterSetterNameDecl(OPT, Member, Sel, S.Context)) { + FindGetterSetterNameDecl(OPT, Member, Sel, S)) { if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(PMDecl)) { // Check the use of this declaration if (S.DiagnoseUseOfDecl(PD, MemberLoc)) @@ -1579,7 +1583,7 @@ ObjCMethodDecl *SMD = nullptr; if (Decl *SDecl = FindGetterSetterNameDecl(OPT, /*Property id*/ nullptr, - SetterSel, S.Context)) + SetterSel, S)) SMD = dyn_cast<ObjCMethodDecl>(SDecl); return new (S.Context) @@ -1613,12 +1617,13 @@ Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member); ObjCInterfaceDecl *IFace = MD->getClassInterface(); ObjCMethodDecl *Getter; - if ((Getter = IFace->lookupClassMethod(Sel))) { + if ((Getter = IFace->lookupClassMethod(Sel, Sema::IsHiddenCallback(S)))) { // Check the use of this method. if (S.DiagnoseUseOfDecl(Getter, MemberLoc)) return ExprError(); } else - Getter = IFace->lookupPrivateMethod(Sel, false); + Getter = + IFace->lookupPrivateClassMethod(Sel, Sema::IsHiddenCallback(S)); // If we found a getter then this may be a valid dot-reference, we // will look for the matching setter, in case it is needed. Selector SetterSel = @@ -1625,11 +1630,13 @@ SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(), S.PP.getSelectorTable(), Member); - ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel); + ObjCMethodDecl *Setter = + IFace->lookupClassMethod(SetterSel, Sema::IsHiddenCallback(S)); if (!Setter) { // If this reference is in an @implementation, also check for 'private' // methods. - Setter = IFace->lookupPrivateMethod(SetterSel, false); + Setter = IFace->lookupPrivateClassMethod(SetterSel, + Sema::IsHiddenCallback(S)); } if (Setter && S.DiagnoseUseOfDecl(Setter, MemberLoc)) Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -87,7 +87,8 @@ } } -static bool HasRedeclarationWithoutAvailabilityInCategory(const Decl *D) { +static bool HasRedeclarationWithoutAvailabilityInCategory(Sema &S, + const Decl *D) { const auto *OMD = dyn_cast<ObjCMethodDecl>(D); if (!OMD) return false; @@ -97,7 +98,8 @@ for (const ObjCCategoryDecl *Cat : OID->visible_categories()) if (ObjCMethodDecl *CatMeth = - Cat->getMethod(OMD->getSelector(), OMD->isInstanceMethod())) + Cat->getMethod(OMD->getSelector(), OMD->isInstanceMethod(), + Sema::IsHiddenCallback(S))) if (!CatMeth->hasAttr<AvailabilityAttr>()) return true; return false; @@ -144,7 +146,7 @@ // Objective-C method declarations in categories are not modelled as // redeclarations, so manually look for a redeclaration in a category // if necessary. - if (Warn && HasRedeclarationWithoutAvailabilityInCategory(D)) + if (Warn && HasRedeclarationWithoutAvailabilityInCategory(*this, D)) Warn = false; // In general, D will point to the most recent redeclaration. However, // for `@class A;` decls, this isn't true -- manually go through the Index: lib/Sema/SemaDeclObjC.cpp =================================================================== --- lib/Sema/SemaDeclObjC.cpp +++ lib/Sema/SemaDeclObjC.cpp @@ -364,9 +364,10 @@ // Warn on deprecated methods under -Wdeprecated-implementations, // and prepare for warning on missing super calls. if (ObjCInterfaceDecl *IC = MDecl->getClassInterface()) { - ObjCMethodDecl *IMD = - IC->lookupMethod(MDecl->getSelector(), MDecl->isInstanceMethod()); - + ObjCMethodDecl *IMD = + IC->lookupMethod(MDecl->getSelector(), MDecl->isInstanceMethod(), + IsHiddenCallback(*this)); + if (IMD) { ObjCImplDecl *ImplDeclOfMethodDef = dyn_cast<ObjCImplDecl>(MDecl->getDeclContext()); @@ -391,7 +392,8 @@ } if (MDecl->getMethodFamily() == OMF_init) { - if (MDecl->isDesignatedInitializerForTheInterface()) { + if (MDecl->isDesignatedInitializerForTheInterface( + IsHiddenCallback(*this))) { getCurFunction()->ObjCIsDesignatedInit = true; getCurFunction()->ObjCWarnForNoDesignatedInitChain = IC->getSuperClass() != nullptr; @@ -417,9 +419,9 @@ getCurFunction()->ObjCShouldCallSuper = true; } else { - const ObjCMethodDecl *SuperMethod = - SuperClass->lookupMethod(MDecl->getSelector(), - MDecl->isInstanceMethod()); + const ObjCMethodDecl *SuperMethod = SuperClass->lookupMethod( + MDecl->getSelector(), MDecl->isInstanceMethod(), + IsHiddenCallback(*this)); getCurFunction()->ObjCShouldCallSuper = (SuperMethod && SuperMethod->hasAttr<ObjCRequiresSuperAttr>()); } @@ -2675,6 +2677,7 @@ !InsMap.count(method->getSelector()) && (!Super || !Super->lookupMethod(method->getSelector(), true /* instance */, + Sema::IsHiddenCallback(S), false /* shallowCategory */, true /* followsSuper */, nullptr /* category */))) { @@ -2690,6 +2693,7 @@ if (ObjCMethodDecl *MethodInClass = IDecl->lookupMethod(method->getSelector(), true /* instance */, + Sema::IsHiddenCallback(S), true /* shallowCategoryLookup */, false /* followSuper */)) if (C || MethodInClass->isPropertyAccessor()) @@ -2707,6 +2711,7 @@ !ClsMap.count(method->getSelector()) && (!Super || !Super->lookupMethod(method->getSelector(), false /* class method */, + Sema::IsHiddenCallback(S), false /* shallowCategoryLookup */, true /* followSuper */, nullptr /* category */))) { @@ -2713,6 +2718,7 @@ // See above comment for instance method lookups. if (C && IDecl->lookupMethod(method->getSelector(), false /* class */, + Sema::IsHiddenCallback(S), true /* shallowCategoryLookup */, false /* followSuper */)) continue; @@ -2754,8 +2760,8 @@ continue; } else { ObjCMethodDecl *ImpMethodDecl = - IMPDecl->getInstanceMethod(I->getSelector()); - assert(CDecl->getInstanceMethod(I->getSelector(), true/*AllowHidden*/) && + IMPDecl->getInstanceMethod(I->getSelector(), IsHiddenCallback(*this)); + assert(CDecl->getInstanceMethod(I->getSelector(), AllDeclsVisible) && "Expected to find the method through lookup as well"); // ImpMethodDecl may be null as in a @dynamic property. if (ImpMethodDecl) { @@ -2780,8 +2786,8 @@ diag::warn_undef_method_impl); } else { ObjCMethodDecl *ImpMethodDecl = - IMPDecl->getClassMethod(I->getSelector()); - assert(CDecl->getClassMethod(I->getSelector(), true/*AllowHidden*/) && + IMPDecl->getClassMethod(I->getSelector(), IsHiddenCallback(*this)); + assert(CDecl->getClassMethod(I->getSelector(), AllDeclsVisible) && "Expected to find the method through lookup as well"); // ImpMethodDecl may be null as in a @dynamic property. if (ImpMethodDecl) { @@ -2856,7 +2862,8 @@ // When checking for methods implemented in the category, skip over // those declared in category class's super class. This is because // the super class must implement the method. - if (SuperIDecl && SuperIDecl->lookupMethod(Sel, true)) + if (SuperIDecl && + SuperIDecl->lookupMethod(Sel, true, IsHiddenCallback(*this))) continue; InsMap.insert(Sel); } @@ -2863,7 +2870,8 @@ for (const auto *I : CatIMPDecl->class_methods()) { Selector Sel = I->getSelector(); - if (SuperIDecl && SuperIDecl->lookupMethod(Sel, false)) + if (SuperIDecl && + SuperIDecl->lookupMethod(Sel, false, IsHiddenCallback(*this))) continue; ClsMap.insert(Sel); } @@ -3822,12 +3830,12 @@ continue; for (const auto *Ext : IDecl->visible_extensions()) { - if (ObjCMethodDecl *GetterMethod - = Ext->getInstanceMethod(Property->getGetterName())) + if (ObjCMethodDecl *GetterMethod = Ext->getInstanceMethod( + Property->getGetterName(), IsHiddenCallback(*this))) GetterMethod->setPropertyAccessor(true); if (!Property->isReadOnly()) - if (ObjCMethodDecl *SetterMethod - = Ext->getInstanceMethod(Property->getSetterName())) + if (ObjCMethodDecl *SetterMethod = Ext->getInstanceMethod( + Property->getSetterName(), IsHiddenCallback(*this))) SetterMethod->setPropertyAccessor(true); } } @@ -4108,7 +4116,7 @@ // Check for a method in this container which matches this selector. ObjCMethodDecl *meth = container->getMethod(Method->getSelector(), Method->isInstanceMethod(), - /*AllowHidden=*/true); + AllDeclsVisible); // If we find one, record it and bail out. if (meth) { @@ -4480,10 +4488,10 @@ const ObjCMethodDecl *PrevMethod = nullptr; if (ObjCImplDecl *ImpDecl = dyn_cast<ObjCImplDecl>(ClassDecl)) { if (MethodType == tok::minus) { - PrevMethod = ImpDecl->getInstanceMethod(Sel); + PrevMethod = ImpDecl->getInstanceMethod(Sel, IsHiddenCallback(*this)); ImpDecl->addInstanceMethod(ObjCMethod); } else { - PrevMethod = ImpDecl->getClassMethod(Sel); + PrevMethod = ImpDecl->getClassMethod(Sel, IsHiddenCallback(*this)); ImpDecl->addClassMethod(ObjCMethod); } @@ -4491,7 +4499,8 @@ // @implementation. if (ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface()) { if (auto *IMD = IDecl->lookupMethod(ObjCMethod->getSelector(), - ObjCMethod->isInstanceMethod())) { + ObjCMethod->isInstanceMethod(), + IsHiddenCallback(*this))) { mergeInterfaceMethodToImpl(*this, ObjCMethod, IMD); // Warn about defining -dealloc in a category. @@ -4776,7 +4785,7 @@ ObjCIvarDecl * Sema::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, - const ObjCPropertyDecl *&PDecl) const { + const ObjCPropertyDecl *&PDecl) { if (Method->isClassMethod()) return nullptr; const ObjCInterfaceDecl *IDecl = Method->getClassInterface(); @@ -4783,6 +4792,7 @@ if (!IDecl) return nullptr; Method = IDecl->lookupMethod(Method->getSelector(), /*isInstance=*/true, + IsHiddenCallback(*this), /*shallowCategoryLookup=*/false, /*followSuper=*/false); if (!Method || !Method->isPropertyAccessor()) Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -12383,8 +12383,8 @@ } if (getCurFunction()->ObjCWarnForNoDesignatedInitChain) { const ObjCMethodDecl *InitMethod = nullptr; - bool isDesignated = - MD->isDesignatedInitializerForTheInterface(&InitMethod); + bool isDesignated = MD->isDesignatedInitializerForTheInterface( + IsHiddenCallback(*this), &InitMethod); assert(isDesignated && InitMethod); (void)isDesignated; Index: lib/Sema/SemaCodeComplete.cpp =================================================================== --- lib/Sema/SemaCodeComplete.cpp +++ lib/Sema/SemaCodeComplete.cpp @@ -5658,14 +5658,16 @@ ObjCMethodDecl *SuperMethod = nullptr; while ((Class = Class->getSuperClass()) && !SuperMethod) { // Check in the class - SuperMethod = Class->getMethod(CurMethod->getSelector(), - CurMethod->isInstanceMethod()); + SuperMethod = Class->getMethod(CurMethod->getSelector(), + CurMethod->isInstanceMethod(), + Sema::IsHiddenCallback(S)); // Check in categories or class extensions. if (!SuperMethod) { for (const auto *Cat : Class->known_categories()) { if ((SuperMethod = Cat->getMethod(CurMethod->getSelector(), - CurMethod->isInstanceMethod()))) + CurMethod->isInstanceMethod(), + Sema::IsHiddenCallback(S)))) break; } } @@ -6520,7 +6522,8 @@ QualType PropertyType = Context.getObjCIdType(); if (Class) { if (ObjCPropertyDecl *Property = Class->FindPropertyDeclaration( - PropertyName, ObjCPropertyQueryKind::OBJC_PR_query_instance)) { + PropertyName, ObjCPropertyQueryKind::OBJC_PR_query_instance, + IsHiddenCallback(*this))) { PropertyType = Property->getType().getNonReferenceType().getUnqualifiedType(); Index: lib/Index/IndexDecl.cpp =================================================================== --- lib/Index/IndexDecl.cpp +++ lib/Index/IndexDecl.cpp @@ -47,8 +47,8 @@ /// user. static bool hasUserDefined(const ObjCMethodDecl *D, const ObjCImplDecl *Container) { - const ObjCMethodDecl *MD = Container->getMethod(D->getSelector(), - D->isInstanceMethod()); + const ObjCMethodDecl *MD = Container->getMethod( + D->getSelector(), D->isInstanceMethod(), AllDeclsVisible); return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition(); } Index: lib/Frontend/Rewrite/RewriteModernObjC.cpp =================================================================== --- lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -592,7 +592,7 @@ bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const { IdentifierInfo* II = &Context->Idents.get("load"); Selector LoadSel = Context->Selectors.getSelector(0, &II); - return OD->getClassMethod(LoadSel) != nullptr; + return OD->getClassMethod(LoadSel, AllDeclsVisible) != nullptr; } StringLiteral *getStringLiteral(StringRef Str) { @@ -910,9 +910,8 @@ static bool mustSynthesizeSetterGetterMethod(ObjCImplementationDecl *IMP, ObjCPropertyDecl *PD, bool getter) { - return getter ? !IMP->getInstanceMethod(PD->getGetterName()) - : !IMP->getInstanceMethod(PD->getSetterName()); - + return !IMP->getInstanceMethod( + getter ? PD->getGetterName() : PD->getSetterName(), AllDeclsVisible); } void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, Index: lib/Edit/RewriteObjCFoundationAPI.cpp =================================================================== --- lib/Edit/RewriteObjCFoundationAPI.cpp +++ lib/Edit/RewriteObjCFoundationAPI.cpp @@ -162,7 +162,8 @@ return false; IFace = maybeAdjustInterfaceForSubscriptingCheck(IFace, Rec, Ctx); - if (const ObjCMethodDecl *MD = IFace->lookupInstanceMethod(subscriptSel)) { + if (const ObjCMethodDecl *MD = + IFace->lookupInstanceMethod(subscriptSel, AllDeclsVisible)) { if (!MD->isUnavailable()) return true; } Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -3735,11 +3735,11 @@ // we want, that just indicates if the decl came from a // property. What we want to know is if the method is defined in // this implementation. - if (!D->getInstanceMethod(PD->getGetterName())) + if (!D->getInstanceMethod(PD->getGetterName(), AllDeclsVisible)) CodeGenFunction(*this).GenerateObjCGetter( const_cast<ObjCImplementationDecl *>(D), PID); if (!PD->isReadOnly() && - !D->getInstanceMethod(PD->getSetterName())) + !D->getInstanceMethod(PD->getSetterName(), AllDeclsVisible)) CodeGenFunction(*this).GenerateObjCSetter( const_cast<ObjCImplementationDecl *>(D), PID); } Index: lib/CodeGen/CGObjCMac.cpp =================================================================== --- lib/CodeGen/CGObjCMac.cpp +++ lib/CodeGen/CGObjCMac.cpp @@ -6187,7 +6187,8 @@ bool CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const { - return OD->getClassMethod(GetNullarySelector("load")) != nullptr; + return OD->getClassMethod(GetNullarySelector("load"), AllDeclsVisible) != + nullptr; } void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID, Index: lib/Analysis/CallGraph.cpp =================================================================== --- lib/Analysis/CallGraph.cpp +++ lib/Analysis/CallGraph.cpp @@ -73,9 +73,9 @@ // Find the callee definition within the same translation unit. Decl *D = nullptr; if (ME->isInstanceMessage()) - D = IDecl->lookupPrivateMethod(Sel); + D = IDecl->lookupPrivateMethod(Sel, AllDeclsVisible); else - D = IDecl->lookupPrivateClassMethod(Sel); + D = IDecl->lookupPrivateClassMethod(Sel, AllDeclsVisible); if (D) { addCalledDecl(D); NumObjCCallEdges++; Index: lib/Analysis/BodyFarm.cpp =================================================================== --- lib/Analysis/BodyFarm.cpp +++ lib/Analysis/BodyFarm.cpp @@ -414,7 +414,7 @@ // is guaranteed to find the shadowing property, if it exists, rather than // the shadowed property. auto *ShadowingProp = PrimaryInterface->FindPropertyVisibleInPrimaryClass( - Prop->getIdentifier(), Prop->getQueryKind()); + Prop->getIdentifier(), Prop->getQueryKind(), AllDeclsVisible); if (ShadowingProp && ShadowingProp != Prop) { IVar = ShadowingProp->getPropertyIvarDecl(); } Index: lib/AST/DeclObjC.cpp =================================================================== --- lib/AST/DeclObjC.cpp +++ lib/AST/DeclObjC.cpp @@ -63,15 +63,16 @@ return nullptr; } +bool clang::AllDeclsVisible(const NamedDecl *ND) { return false; } + // Get the local instance/class method declared in this interface. -ObjCMethodDecl * -ObjCContainerDecl::getMethod(Selector Sel, bool isInstance, - bool AllowHidden) const { +ObjCMethodDecl *ObjCContainerDecl::getMethod(Selector Sel, bool isInstance, + IsHiddenFunction IsHidden) const { // If this context is a hidden protocol definition, don't find any // methods there. if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) { if (const ObjCProtocolDecl *Def = Proto->getDefinition()) - if (Def->isHidden() && !AllowHidden) + if (IsHidden(Def)) return nullptr; } @@ -99,7 +100,7 @@ /// property. This is because, user must provide a setter method for the /// category's 'readwrite' property. bool ObjCContainerDecl::HasUserDeclaredSetterMethod( - const ObjCPropertyDecl *Property) const { + const ObjCPropertyDecl *Property, IsHiddenFunction IsHidden) const { Selector Sel = Property->getSetterName(); lookup_result R = lookup(Sel); for (lookup_iterator Meth = R.begin(), MethEnd = R.end(); @@ -113,7 +114,7 @@ // Also look into categories, including class extensions, looking // for a user declared instance method. for (const auto *Cat : ID->visible_categories()) { - if (ObjCMethodDecl *MD = Cat->getInstanceMethod(Sel)) + if (ObjCMethodDecl *MD = Cat->getInstanceMethod(Sel, IsHidden)) if (!MD->isImplicit()) return true; if (Cat->IsClassExtension()) @@ -132,13 +133,13 @@ // Also look into protocols, for a user declared instance method. for (const auto *Proto : ID->all_referenced_protocols()) - if (Proto->HasUserDeclaredSetterMethod(Property)) + if (Proto->HasUserDeclaredSetterMethod(Property, IsHidden)) return true; // And in its super class. ObjCInterfaceDecl *OSC = ID->getSuperClass(); while (OSC) { - if (OSC->HasUserDeclaredSetterMethod(Property)) + if (OSC->HasUserDeclaredSetterMethod(Property, IsHidden)) return true; OSC = OSC->getSuperClass(); } @@ -145,7 +146,7 @@ } if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(this)) for (const auto *PI : PD->protocols()) - if (PI->HasUserDeclaredSetterMethod(Property)) + if (PI->HasUserDeclaredSetterMethod(Property, IsHidden)) return true; return false; } @@ -153,12 +154,13 @@ ObjCPropertyDecl * ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC, const IdentifierInfo *propertyID, - ObjCPropertyQueryKind queryKind) { + ObjCPropertyQueryKind queryKind, + IsHiddenFunction IsHidden) { // If this context is a hidden protocol definition, don't find any // property. if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(DC)) { if (const ObjCProtocolDecl *Def = Proto->getDefinition()) - if (Def->isHidden()) + if (IsHidden(Def)) return nullptr; } @@ -166,9 +168,8 @@ // This comes before property is looked up in primary class. if (auto *IDecl = dyn_cast<ObjCInterfaceDecl>(DC)) { for (const auto *Ext : IDecl->visible_extensions()) - if (ObjCPropertyDecl *PD = ObjCPropertyDecl::findPropertyDecl(Ext, - propertyID, - queryKind)) + if (ObjCPropertyDecl *PD = + findPropertyDecl(Ext, propertyID, queryKind, IsHidden)) return PD; } @@ -210,13 +211,14 @@ /// FindPropertyDeclaration - Finds declaration of the property given its name /// in 'PropertyId' and returns it. It returns 0, if not found. -ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration( - const IdentifierInfo *PropertyId, - ObjCPropertyQueryKind QueryKind) const { +ObjCPropertyDecl * +ObjCContainerDecl::FindPropertyDeclaration(const IdentifierInfo *PropertyId, + ObjCPropertyQueryKind QueryKind, + IsHiddenFunction IsHidden) const { // Don't find properties within hidden protocol definitions. if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) { if (const ObjCProtocolDecl *Def = Proto->getDefinition()) - if (Def->isHidden()) + if (IsHidden(Def)) return nullptr; } @@ -224,7 +226,8 @@ // the class itself. if (const auto *ClassDecl = dyn_cast<ObjCInterfaceDecl>(this)) { for (const auto *Ext : ClassDecl->visible_extensions()) { - if (auto *P = Ext->FindPropertyDeclaration(PropertyId, QueryKind)) + if (auto *P = + Ext->FindPropertyDeclaration(PropertyId, QueryKind, IsHidden)) return P; } } @@ -231,7 +234,7 @@ if (ObjCPropertyDecl *PD = ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId, - QueryKind)) + QueryKind, IsHidden)) return PD; switch (getKind()) { @@ -240,8 +243,8 @@ case Decl::ObjCProtocol: { const ObjCProtocolDecl *PID = cast<ObjCProtocolDecl>(this); for (const auto *I : PID->protocols()) - if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId, - QueryKind)) + if (ObjCPropertyDecl *P = + I->FindPropertyDeclaration(PropertyId, QueryKind, IsHidden)) return P; break; } @@ -250,20 +253,21 @@ // Look through categories (but not extensions; they were handled above). for (const auto *Cat : OID->visible_categories()) { if (!Cat->IsClassExtension()) - if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration( - PropertyId, QueryKind)) + if (ObjCPropertyDecl *P = + Cat->FindPropertyDeclaration(PropertyId, QueryKind, IsHidden)) return P; } // Look through protocols. for (const auto *I : OID->all_referenced_protocols()) - if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId, - QueryKind)) + if (ObjCPropertyDecl *P = + I->FindPropertyDeclaration(PropertyId, QueryKind, IsHidden)) return P; // Finally, check the super class. if (const ObjCInterfaceDecl *superClass = OID->getSuperClass()) - return superClass->FindPropertyDeclaration(PropertyId, QueryKind); + return superClass->FindPropertyDeclaration(PropertyId, QueryKind, + IsHidden); break; } case Decl::ObjCCategory: { @@ -271,8 +275,8 @@ // Look through protocols. if (!OCD->IsClassExtension()) for (const auto *I : OCD->protocols()) - if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId, - QueryKind)) + if (ObjCPropertyDecl *P = + I->FindPropertyDeclaration(PropertyId, QueryKind, IsHidden)) return P; break; } @@ -342,10 +346,9 @@ /// with name 'PropertyId' in the primary class; including those in protocols /// (direct or indirect) used by the primary class. /// -ObjCPropertyDecl * -ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass( - IdentifierInfo *PropertyId, - ObjCPropertyQueryKind QueryKind) const { +ObjCPropertyDecl *ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass( + IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind, + IsHiddenFunction IsHidden) const { // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) return nullptr; @@ -355,13 +358,13 @@ if (ObjCPropertyDecl *PD = ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId, - QueryKind)) + QueryKind, IsHidden)) return PD; // Look through protocols. for (const auto *I : all_referenced_protocols()) - if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId, - QueryKind)) + if (ObjCPropertyDecl *P = + I->FindPropertyDeclaration(PropertyId, QueryKind, IsHidden)) return P; return nullptr; @@ -537,8 +540,9 @@ } } -bool ObjCInterfaceDecl::isDesignatedInitializer(Selector Sel, - const ObjCMethodDecl **InitMethod) const { +bool ObjCInterfaceDecl::isDesignatedInitializer( + Selector Sel, const ObjCMethodDecl **InitMethod, + IsHiddenFunction IsHidden) const { bool HasCompleteDef = isThisDeclarationADefinition(); // During deserialization the data record for the ObjCInterfaceDecl could // be made invariant by reusing the canonical decl. Take this into account @@ -558,7 +562,7 @@ if (!IFace) return false; - if (const ObjCMethodDecl *MD = IFace->getInstanceMethod(Sel)) { + if (const ObjCMethodDecl *MD = IFace->getInstanceMethod(Sel, IsHidden)) { if (MD->isThisDeclarationADesignatedInitializer()) { if (InitMethod) *InitMethod = MD; @@ -566,7 +570,7 @@ } } for (const auto *Ext : IFace->visible_extensions()) { - if (const ObjCMethodDecl *MD = Ext->getInstanceMethod(Sel)) { + if (const ObjCMethodDecl *MD = Ext->getInstanceMethod(Sel, IsHidden)) { if (MD->isThisDeclarationADesignatedInitializer()) { if (InitMethod) *InitMethod = MD; @@ -661,6 +665,7 @@ /// in this category is ignored. ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, bool isInstance, + IsHiddenFunction IsHidden, bool shallowCategoryLookup, bool followSuper, const ObjCCategoryDecl *C) const @@ -677,18 +682,18 @@ while (ClassDecl) { // 1. Look through primary class. - if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance))) + if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance, IsHidden))) return MethodDecl; // 2. Didn't find one yet - now look through categories. for (const auto *Cat : ClassDecl->visible_categories()) - if ((MethodDecl = Cat->getMethod(Sel, isInstance))) + if ((MethodDecl = Cat->getMethod(Sel, isInstance, IsHidden))) if (C != Cat || !MethodDecl->isImplicit()) return MethodDecl; // 3. Didn't find one yet - look through primary class's protocols. for (const auto *I : ClassDecl->protocols()) - if ((MethodDecl = I->lookupMethod(Sel, isInstance))) + if ((MethodDecl = I->lookupMethod(Sel, isInstance, IsHidden))) return MethodDecl; // 4. Didn't find one yet - now look through categories' protocols @@ -699,7 +704,7 @@ Cat->getReferencedProtocols(); for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), E = Protocols.end(); I != E; ++I) - if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance))) + if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance, IsHidden))) if (C != Cat || !MethodDecl->isImplicit()) return MethodDecl; } @@ -717,9 +722,9 @@ // Will search "local" class/category implementations for a method decl. // If failed, then we search in class's root for an instance method. // Returns 0 if no method is found. -ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod( - const Selector &Sel, - bool Instance) const { +ObjCMethodDecl * +ObjCInterfaceDecl::lookupPrivateMethod(const Selector &Sel, bool Instance, + IsHiddenFunction IsHidden) const { // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) return nullptr; @@ -729,26 +734,26 @@ ObjCMethodDecl *Method = nullptr; if (ObjCImplementationDecl *ImpDecl = getImplementation()) - Method = Instance ? ImpDecl->getInstanceMethod(Sel) - : ImpDecl->getClassMethod(Sel); + Method = Instance ? ImpDecl->getInstanceMethod(Sel, IsHidden) + : ImpDecl->getClassMethod(Sel, IsHidden); // Look through local category implementations associated with the class. if (!Method) - Method = getCategoryMethod(Sel, Instance); + Method = getCategoryMethod(Sel, Instance, IsHidden); // Before we give up, check if the selector is an instance method. // But only in the root. This matches gcc's behavior and what the // runtime expects. if (!Instance && !Method && !getSuperClass()) { - Method = lookupInstanceMethod(Sel); + Method = lookupInstanceMethod(Sel, IsHidden); // Look through local category implementations associated // with the root class. if (!Method) - Method = lookupPrivateMethod(Sel, true); + Method = lookupPrivateMethod(Sel, true, IsHidden); } if (!Method && getSuperClass()) - return getSuperClass()->lookupPrivateMethod(Sel, Instance); + return getSuperClass()->lookupPrivateMethod(Sel, Instance, IsHidden); return Method; } @@ -779,7 +784,7 @@ } bool ObjCMethodDecl::isDesignatedInitializerForTheInterface( - const ObjCMethodDecl **InitMethod) const { + IsHiddenFunction IsHidden, const ObjCMethodDecl **InitMethod) const { if (getMethodFamily() != OMF_init) return false; const DeclContext *DC = getDeclContext(); @@ -786,7 +791,7 @@ if (isa<ObjCProtocolDecl>(DC)) return false; if (const ObjCInterfaceDecl *ID = getClassInterface()) - return ID->isDesignatedInitializer(getSelector(), InitMethod); + return ID->isDesignatedInitializer(getSelector(), InitMethod, IsHidden); return false; } @@ -858,24 +863,28 @@ if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) { if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD)) if (!ImplD->isInvalidDecl()) - Redecl = ImplD->getMethod(getSelector(), isInstanceMethod()); + Redecl = ImplD->getMethod(getSelector(), isInstanceMethod(), + AllDeclsVisible); } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) { if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD)) if (!ImplD->isInvalidDecl()) - Redecl = ImplD->getMethod(getSelector(), isInstanceMethod()); + Redecl = ImplD->getMethod(getSelector(), isInstanceMethod(), + AllDeclsVisible); } else if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) { if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) if (!IFD->isInvalidDecl()) - Redecl = IFD->getMethod(getSelector(), isInstanceMethod()); + Redecl = IFD->getMethod(getSelector(), isInstanceMethod(), + AllDeclsVisible); } else if (ObjCCategoryImplDecl *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) { if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl()) if (!CatD->isInvalidDecl()) - Redecl = CatD->getMethod(getSelector(), isInstanceMethod()); + Redecl = CatD->getMethod(getSelector(), isInstanceMethod(), + AllDeclsVisible); } } @@ -888,7 +897,8 @@ if (!Redecl && isRedeclaration()) { // This is the last redeclaration, go back to the first method. return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(), - isInstanceMethod()); + isInstanceMethod(), + AllDeclsVisible); } return Redecl ? Redecl : this; @@ -899,23 +909,22 @@ if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) { if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) - if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(), - isInstanceMethod())) + if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(), isInstanceMethod(), + AllDeclsVisible)) return MD; } else if (ObjCCategoryImplDecl *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) { if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl()) - if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(), - isInstanceMethod())) + if (ObjCMethodDecl *MD = CatD->getMethod( + getSelector(), isInstanceMethod(), AllDeclsVisible)) return MD; } if (isRedeclaration()) { // It is possible that we have not done deserializing the ObjCMethod yet. - ObjCMethodDecl *MD = - cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(), - isInstanceMethod()); + ObjCMethodDecl *MD = cast<ObjCContainerDecl>(CtxD)->getMethod( + getSelector(), isInstanceMethod(), AllDeclsVisible); return MD ? MD : this; } @@ -1137,7 +1146,7 @@ if (ObjCMethodDecl * Overridden = Container->getMethod(Method->getSelector(), Method->isInstanceMethod(), - /*AllowHidden=*/true)) + AllDeclsVisible)) if (Method != Overridden) { // We found an override at this category; there is no need to look // into its protocols. @@ -1154,7 +1163,7 @@ if (const ObjCMethodDecl * Overridden = Container->getMethod(Method->getSelector(), Method->isInstanceMethod(), - /*AllowHidden=*/true)) + AllDeclsVisible)) if (Method != Overridden) { // We found an override at this level; there is no need to look // into other protocols or categories. @@ -1205,7 +1214,7 @@ // interface as starting point. if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(), Method->isInstanceMethod(), - /*AllowHidden=*/true)) + AllDeclsVisible)) Method = IFaceMeth; CollectOverriddenMethods(ID, Method, overridden); @@ -1218,7 +1227,7 @@ // interface as starting point. if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(), Method->isInstanceMethod(), - /*AllowHidden=*/true)) + AllDeclsVisible)) Method = IFaceMeth; CollectOverriddenMethods(ID, Method, overridden); @@ -1234,8 +1243,9 @@ const ObjCMethodDecl *Method = this; if (Method->isRedeclaration()) { - Method = cast<ObjCContainerDecl>(Method->getDeclContext())-> - getMethod(Method->getSelector(), Method->isInstanceMethod()); + Method = cast<ObjCContainerDecl>(Method->getDeclContext()) + ->getMethod(Method->getSelector(), Method->isInstanceMethod(), + AllDeclsVisible); } if (Method->isOverriding()) { @@ -1628,10 +1638,11 @@ } ObjCMethodDecl * -ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const { +ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel, + IsHiddenFunction IsHidden) const { for (const auto *Cat : visible_categories()) { if (ObjCCategoryImplDecl *Impl = Cat->getImplementation()) - if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel)) + if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel, IsHidden)) return MD; } @@ -1638,10 +1649,12 @@ return nullptr; } -ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const { +ObjCMethodDecl * +ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel, + IsHiddenFunction IsHidden) const { for (const auto *Cat : visible_categories()) { if (ObjCCategoryImplDecl *Impl = Cat->getImplementation()) - if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel)) + if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel, IsHidden)) return MD; } @@ -1839,21 +1852,22 @@ // lookupMethod - Lookup a instance/class method in the protocol and protocols // it inherited. -ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel, - bool isInstance) const { +ObjCMethodDecl * +ObjCProtocolDecl::lookupMethod(Selector Sel, bool isInstance, + IsHiddenFunction IsHidden) const { ObjCMethodDecl *MethodDecl = nullptr; // If there is no definition or the definition is hidden, we don't find // anything. const ObjCProtocolDecl *Def = getDefinition(); - if (!Def || Def->isHidden()) + if (!Def || IsHidden(Def)) return nullptr; - if ((MethodDecl = getMethod(Sel, isInstance))) + if ((MethodDecl = getMethod(Sel, isInstance, IsHidden))) return MethodDecl; for (const auto *I : protocols()) - if ((MethodDecl = I->lookupMethod(Sel, isInstance))) + if ((MethodDecl = I->lookupMethod(Sel, isInstance, IsHidden))) return MethodDecl; return nullptr; } Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -410,8 +410,8 @@ // Add redeclared method here. for (const auto *Ext : ID->known_extensions()) { if (ObjCMethodDecl *RedeclaredMethod = - Ext->getMethod(ObjCMethod->getSelector(), - ObjCMethod->isInstanceMethod())) + Ext->getMethod(ObjCMethod->getSelector(), + ObjCMethod->isInstanceMethod(), AllDeclsVisible)) Redeclared.push_back(RedeclaredMethod); } } Index: lib/ARCMigrate/ObjCMT.cpp =================================================================== --- lib/ARCMigrate/ObjCMT.cpp +++ lib/ARCMigrate/ObjCMT.cpp @@ -1172,7 +1172,8 @@ SelectorTable::constructSetterSelector(PP.getIdentifierTable(), PP.getSelectorTable(), getterName); - ObjCMethodDecl *SetterMethod = D->getInstanceMethod(SetterSelector); + ObjCMethodDecl *SetterMethod = + D->getInstanceMethod(SetterSelector, AllDeclsVisible); unsigned LengthOfPrefix = 0; if (!SetterMethod) { // try a different naming convention for getter: isXxxxx @@ -1195,7 +1196,7 @@ SelectorTable::constructSetterSelector(PP.getIdentifierTable(), PP.getSelectorTable(), getterName); - SetterMethod = D->getInstanceMethod(SetterSelector); + SetterMethod = D->getInstanceMethod(SetterSelector, AllDeclsVisible); } } } @@ -1703,12 +1704,12 @@ return; for (const auto *MD : ImplD->instance_methods()) { - if (MD->isDeprecated() || - MD->getMethodFamily() != OMF_init || - MD->isDesignatedInitializerForTheInterface()) + if (MD->isDeprecated() || MD->getMethodFamily() != OMF_init || + MD->isDesignatedInitializerForTheInterface(AllDeclsVisible)) continue; - const ObjCMethodDecl *IFaceM = IFace->getMethod(MD->getSelector(), - /*isInstance=*/true); + const ObjCMethodDecl *IFaceM = + IFace->getMethod(MD->getSelector(), + /*isInstance=*/true, AllDeclsVisible); if (!IFaceM) continue; if (hasSuperInitCall(MD)) { Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -1531,6 +1531,13 @@ return !D->isHidden() || isVisibleSlow(D); } + /// "Is this declaration hidden?" callback used for ObjC lookups. + struct IsHiddenCallback { + Sema &S; + IsHiddenCallback(Sema &S) : S(S) {} + bool operator()(const NamedDecl *D) const { return !S.isVisible(D); } + }; + /// Determine whether any declaration of an entity is visible. bool hasVisibleDeclaration(const NamedDecl *D, @@ -3364,7 +3371,7 @@ /// it property has a backing ivar, returns this ivar; otherwise, returns NULL. /// It also returns ivar's property on success. ObjCIvarDecl *GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, - const ObjCPropertyDecl *&PDecl) const; + const ObjCPropertyDecl *&PDecl); /// Called by ActOnProperty to handle \@property declarations in /// class extensions. Index: include/clang/AST/DeclObjC.h =================================================================== --- include/clang/AST/DeclObjC.h +++ include/clang/AST/DeclObjC.h @@ -89,7 +89,15 @@ const SourceLocation *Locs, ASTContext &Ctx); }; +/// A callback used to determine which declarations should be visible to ObjC +/// name lookups. +// FIXME: This should not be necessary; the name lookup logic should be in Sema. +typedef llvm::function_ref<bool(const NamedDecl*)> IsHiddenFunction; +/// An IsHiddenFunction callback for the case where all declarations should be +/// considered to be visible. +bool AllDeclsVisible(const NamedDecl*); + /// ObjCMethodDecl - Represents an instance or class method declaration. /// ObjC methods can be declared within 4 contexts: class interfaces, /// categories, protocols, and class implementations. While C++ member @@ -480,6 +488,7 @@ /// the method declaration that was marked with the designated initializer /// attribute. bool isDesignatedInitializerForTheInterface( + IsHiddenFunction IsHidden, const ObjCMethodDecl **InitMethod = nullptr) const; /// \brief Determine whether this method has a body. @@ -906,7 +915,8 @@ /// Lookup a property by name in the specified DeclContext. static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC, const IdentifierInfo *propertyID, - ObjCPropertyQueryKind queryKind); + ObjCPropertyQueryKind queryKind, + IsHiddenFunction IsHidden); static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCProperty; } @@ -1021,20 +1031,22 @@ // Get the local instance/class method declared in this interface. ObjCMethodDecl *getMethod(Selector Sel, bool isInstance, - bool AllowHidden = false) const; + IsHiddenFunction IsHidden) const; ObjCMethodDecl *getInstanceMethod(Selector Sel, - bool AllowHidden = false) const { - return getMethod(Sel, true/*isInstance*/, AllowHidden); + IsHiddenFunction IsHidden) const { + return getMethod(Sel, true/*isInstance*/, IsHidden); } - ObjCMethodDecl *getClassMethod(Selector Sel, bool AllowHidden = false) const { - return getMethod(Sel, false/*isInstance*/, AllowHidden); + ObjCMethodDecl *getClassMethod(Selector Sel, + IsHiddenFunction IsHidden) const { + return getMethod(Sel, false/*isInstance*/, IsHidden); } - bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const; + bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P, + IsHiddenFunction IsHidden) const; ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const; - ObjCPropertyDecl * - FindPropertyDeclaration(const IdentifierInfo *PropertyId, - ObjCPropertyQueryKind QueryKind) const; + ObjCPropertyDecl *FindPropertyDeclaration(const IdentifierInfo *PropertyId, + ObjCPropertyQueryKind QueryKind, + IsHiddenFunction IsHidden) const; typedef llvm::DenseMap<std::pair<IdentifierInfo*, unsigned/*isClassProperty*/>, @@ -1283,11 +1295,14 @@ ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const; // Get the local instance/class method declared in a category. - ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const; - ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const; - ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const { - return isInstance ? getCategoryInstanceMethod(Sel) - : getCategoryClassMethod(Sel); + ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel, + IsHiddenFunction IsHidden) const; + ObjCMethodDecl *getCategoryClassMethod(Selector Sel, + IsHiddenFunction IsHidden) const; + ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance, + IsHiddenFunction IsHidden) const { + return isInstance ? getCategoryInstanceMethod(Sel, IsHidden) + : getCategoryClassMethod(Sel, IsHidden); } typedef ObjCProtocolList::iterator protocol_iterator; @@ -1444,9 +1459,13 @@ /// /// \param InitMethod if non-null and the function returns true, it receives /// the method that was marked as a designated initializer. - bool - isDesignatedInitializer(Selector Sel, - const ObjCMethodDecl **InitMethod = nullptr) const; + bool isDesignatedInitializer(Selector Sel, + const ObjCMethodDecl **InitMethod, + IsHiddenFunction IsHidden) const; + bool isDesignatedInitializer(Selector Sel, + IsHiddenFunction IsHidden) const { + return isDesignatedInitializer(Sel, nullptr, IsHidden); + } /// \brief Determine whether this particular declaration of this class is /// actually also a definition. @@ -1720,7 +1739,8 @@ ObjCPropertyDecl *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId, - ObjCPropertyQueryKind QueryKind) const; + ObjCPropertyQueryKind QueryKind, + IsHiddenFunction IsHidden) const; void collectPropertiesToImplement(PropertyMap &PM, PropertyDeclOrder &PO) const override; @@ -1759,36 +1779,45 @@ // Lookup a method. First, we search locally. If a method isn't // found, we search referenced protocols and class categories. ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance, + IsHiddenFunction IsHidden, bool shallowCategoryLookup = false, bool followSuper = true, const ObjCCategoryDecl *C = nullptr) const; /// Lookup an instance method for a given selector. - ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const { - return lookupMethod(Sel, true/*isInstance*/); + ObjCMethodDecl *lookupInstanceMethod(Selector Sel, + IsHiddenFunction IsHidden) const { + return lookupMethod(Sel, true/*isInstance*/, IsHidden); } /// Lookup a class method for a given selector. - ObjCMethodDecl *lookupClassMethod(Selector Sel) const { - return lookupMethod(Sel, false/*isInstance*/); + ObjCMethodDecl *lookupClassMethod(Selector Sel, + IsHiddenFunction IsHidden) const { + return lookupMethod(Sel, false/*isInstance*/, IsHidden); } ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName); /// \brief Lookup a method in the classes implementation hierarchy. ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel, - bool Instance=true) const; - - ObjCMethodDecl *lookupPrivateClassMethod(const Selector &Sel) { - return lookupPrivateMethod(Sel, false); + bool Instance, + IsHiddenFunction IsHidden) const; + ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel, + IsHiddenFunction IsHidden) const { + return lookupPrivateMethod(Sel, true, IsHidden); } + ObjCMethodDecl *lookupPrivateClassMethod(const Selector &Sel, + IsHiddenFunction IsHidden) { + return lookupPrivateMethod(Sel, false, IsHidden); + } /// \brief Lookup a setter or getter in the class hierarchy, /// including in all categories except for category passed /// as argument. ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel, + IsHiddenFunction IsHidden, const ObjCCategoryDecl *Cat, bool IsClassProperty) const { - return lookupMethod(Sel, !IsClassProperty/*isInstance*/, + return lookupMethod(Sel, !IsClassProperty/*isInstance*/, IsHidden, false/*shallowCategoryLookup*/, true /* followsSuper */, Cat); @@ -2092,12 +2121,15 @@ // Lookup a method. First, we search locally. If a method isn't // found, we search referenced protocols and class categories. - ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const; - ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const { - return lookupMethod(Sel, true/*isInstance*/); + ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance, + IsHiddenFunction IsHidden) const; + ObjCMethodDecl *lookupInstanceMethod(Selector Sel, + IsHiddenFunction IsHidden) const { + return lookupMethod(Sel, true/*isInstance*/, IsHidden); } - ObjCMethodDecl *lookupClassMethod(Selector Sel) const { - return lookupMethod(Sel, false/*isInstance*/); + ObjCMethodDecl *lookupClassMethod(Selector Sel, + IsHiddenFunction IsHidden) const { + return lookupMethod(Sel, false/*isInstance*/, IsHidden); } /// \brief Determine whether this protocol has a definition.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits