diff options
Diffstat (limited to 'lib/Sema/SemaExprObjC.cpp')
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 183 |
1 files changed, 66 insertions, 117 deletions
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 9c3b51c..63b7485 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -218,7 +218,9 @@ static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc, S.Diag(Loc, diag::err_undeclared_nsnumber); return nullptr; } - + } + + if (S.NSNumberPointer.isNull()) { // generate the pointer to NSNumber type. QualType NSNumberObject = CX.getObjCInterfaceType(S.NSNumberDecl); S.NSNumberPointer = CX.getObjCObjectPointerType(NSNumberObject); @@ -1041,7 +1043,7 @@ ExprResult Sema::ParseObjCSelectorExpression(Selector Sel, SourceLocation RParenLoc, bool WarnMultipleSelectors) { ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel, - SourceRange(LParenLoc, RParenLoc), false, false); + SourceRange(LParenLoc, RParenLoc)); if (!Method) Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(LParenLoc, RParenLoc)); @@ -1059,15 +1061,11 @@ ExprResult Sema::ParseObjCSelectorExpression(Selector Sel, } else DiagnoseMismatchedSelectors(*this, AtLoc, Method, LParenLoc, RParenLoc, WarnMultipleSelectors); - + if (Method && Method->getImplementationControl() != ObjCMethodDecl::Optional && - !getSourceManager().isInSystemHeader(Method->getLocation())) { - llvm::DenseMap<Selector, SourceLocation>::iterator Pos - = ReferencedSelectors.find(Sel); - if (Pos == ReferencedSelectors.end()) - ReferencedSelectors.insert(std::make_pair(Sel, AtLoc)); - } + !getSourceManager().isInSystemHeader(Method->getLocation())) + ReferencedSelectors.insert(std::make_pair(Sel, AtLoc)); // In ARC, forbid the user from using @selector for // retain/release/autorelease/dealloc/retainCount. @@ -1507,64 +1505,6 @@ ObjCMethodDecl *Sema::LookupMethodInQualifiedType(Selector Sel, return nullptr; } -static void DiagnoseARCUseOfWeakReceiver(Sema &S, Expr *Receiver) { - if (!Receiver) - return; - - if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Receiver)) - Receiver = OVE->getSourceExpr(); - - Expr *RExpr = Receiver->IgnoreParenImpCasts(); - SourceLocation Loc = RExpr->getLocStart(); - QualType T = RExpr->getType(); - const ObjCPropertyDecl *PDecl = nullptr; - const ObjCMethodDecl *GDecl = nullptr; - if (PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(RExpr)) { - RExpr = POE->getSyntacticForm(); - if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(RExpr)) { - if (PRE->isImplicitProperty()) { - GDecl = PRE->getImplicitPropertyGetter(); - if (GDecl) { - T = GDecl->getReturnType(); - } - } - else { - PDecl = PRE->getExplicitProperty(); - if (PDecl) { - T = PDecl->getType(); - } - } - } - } - else if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(RExpr)) { - // See if receiver is a method which envokes a synthesized getter - // backing a 'weak' property. - ObjCMethodDecl *Method = ME->getMethodDecl(); - if (Method && Method->getSelector().getNumArgs() == 0) { - PDecl = Method->findPropertyDecl(); - if (PDecl) - T = PDecl->getType(); - } - } - - if (T.getObjCLifetime() != Qualifiers::OCL_Weak) { - if (!PDecl) - return; - if (!(PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)) - return; - } - - S.Diag(Loc, diag::warn_receiver_is_weak) - << ((!PDecl && !GDecl) ? 0 : (PDecl ? 1 : 2)); - - if (PDecl) - S.Diag(PDecl->getLocation(), diag::note_property_declare); - else if (GDecl) - S.Diag(GDecl->getLocation(), diag::note_method_declared_at) << GDecl; - - S.Diag(Loc, diag::note_arc_assign_to_strong); -} - /// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an /// objective C interface. This is a property reference expression. ExprResult Sema:: @@ -1751,29 +1691,30 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, IsSuper = true; if (ObjCMethodDecl *CurMethod = tryCaptureObjCSelf(receiverNameLoc)) { - if (CurMethod->isInstanceMethod()) { - ObjCInterfaceDecl *Super = - CurMethod->getClassInterface()->getSuperClass(); - if (!Super) { - // The current class does not have a superclass. - Diag(receiverNameLoc, diag::error_root_class_cannot_use_super) - << CurMethod->getClassInterface()->getIdentifier(); - return ExprError(); + if (ObjCInterfaceDecl *Class = CurMethod->getClassInterface()) { + if (CurMethod->isInstanceMethod()) { + ObjCInterfaceDecl *Super = Class->getSuperClass(); + if (!Super) { + // The current class does not have a superclass. + Diag(receiverNameLoc, diag::error_root_class_cannot_use_super) + << Class->getIdentifier(); + return ExprError(); + } + QualType T = Context.getObjCInterfaceType(Super); + T = Context.getObjCObjectPointerType(T); + + return HandleExprPropertyRefExpr(T->getAsObjCInterfacePointerType(), + /*BaseExpr*/nullptr, + SourceLocation()/*OpLoc*/, + &propertyName, + propertyNameLoc, + receiverNameLoc, T, true); } - QualType T = Context.getObjCInterfaceType(Super); - T = Context.getObjCObjectPointerType(T); - - return HandleExprPropertyRefExpr(T->getAsObjCInterfacePointerType(), - /*BaseExpr*/nullptr, - SourceLocation()/*OpLoc*/, - &propertyName, - propertyNameLoc, - receiverNameLoc, T, true); - } - // Otherwise, if this is a class method, try dispatching to our - // superclass. - IFace = CurMethod->getClassInterface()->getSuperClass(); + // Otherwise, if this is a class method, try dispatching to our + // superclass. + IFace = Class->getSuperClass(); + } } } @@ -2452,8 +2393,11 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, if (ObjCMethodDecl *BestMethod = SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod())) Method = BestMethod; - if (!AreMultipleMethodsInGlobalPool(Sel, Method->isInstanceMethod())) + if (!AreMultipleMethodsInGlobalPool(Sel, Method, + SourceRange(LBracLoc, RBracLoc), + receiverIsId)) { DiagnoseUseOfDecl(Method, SelLoc); + } } } else if (ReceiverType->isObjCClassType() || ReceiverType->isObjCQualifiedClassType()) { @@ -2491,14 +2435,12 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, // If not messaging 'self', look for any factory method named 'Sel'. if (!Receiver || !isSelfExpr(Receiver)) { Method = LookupFactoryMethodInGlobalPool(Sel, - SourceRange(LBracLoc, RBracLoc), - true); + SourceRange(LBracLoc, RBracLoc)); if (!Method) { // If no class (factory) method was found, check if an _instance_ // method of the same name exists in the root class only. Method = LookupInstanceMethodInGlobalPool(Sel, - SourceRange(LBracLoc, RBracLoc), - true); + SourceRange(LBracLoc, RBracLoc)); if (Method) if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) { @@ -2575,6 +2517,14 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, if (OCIType->qual_empty()) { Method = LookupInstanceMethodInGlobalPool(Sel, SourceRange(LBracLoc, RBracLoc)); + if (Method) { + if (auto BestMethod = + SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod())) + Method = BestMethod; + AreMultipleMethodsInGlobalPool(Sel, Method, + SourceRange(LBracLoc, RBracLoc), + true); + } if (Method && !forwardClass) Diag(SelLoc, diag::warn_maynot_respond) << OCIType->getInterfaceDecl()->getIdentifier() @@ -2757,15 +2707,6 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, } if (getLangOpts().ObjCAutoRefCount) { - // Do not warn about IBOutlet weak property receivers being set to null - // as this cannot asynchronously happen. - bool WarnWeakReceiver = true; - if (isImplicit && Method) - if (const ObjCPropertyDecl *PropertyDecl = Method->findPropertyDecl()) - WarnWeakReceiver = !PropertyDecl->hasAttr<IBOutletAttr>(); - if (WarnWeakReceiver) - DiagnoseARCUseOfWeakReceiver(*this, Receiver); - // In ARC, annotate delegate init calls. if (Result->getMethodFamily() == OMF_init && (SuperLoc.isValid() || isSelfExpr(Receiver))) { @@ -2796,7 +2737,9 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, } } } - + + CheckObjCCircularContainer(Result); + return MaybeBindToTemporary(Result); } @@ -2805,8 +2748,7 @@ static void RemoveSelectorFromWarningCache(Sema &S, Expr* Arg) { dyn_cast<ObjCSelectorExpr>(Arg->IgnoreParenCasts())) { Selector Sel = OSE->getSelector(); SourceLocation Loc = OSE->getAtLoc(); - llvm::DenseMap<Selector, SourceLocation>::iterator Pos - = S.ReferencedSelectors.find(Sel); + auto Pos = S.ReferencedSelectors.find(Sel); if (Pos != S.ReferencedSelectors.end() && Pos->second == Loc) S.ReferencedSelectors.erase(Pos); } @@ -3028,17 +2970,20 @@ namespace { /// Some declaration references are okay. ACCResult VisitDeclRefExpr(DeclRefExpr *e) { - // References to global constants from system headers are okay. - // These are things like 'kCFStringTransformToLatin'. They are - // can also be assumed to be immune to retains. VarDecl *var = dyn_cast<VarDecl>(e->getDecl()); + // References to global constants are okay. if (isAnyRetainable(TargetClass) && isAnyRetainable(SourceClass) && var && var->getStorageClass() == SC_Extern && - var->getType().isConstQualified() && - Context.getSourceManager().isInSystemHeader(var->getLocation())) { - return ACC_bottom; + var->getType().isConstQualified()) { + + // In system headers, they can also be assumed to be immune to retains. + // These are things like 'kCFStringTransformToLatin'. + if (Context.getSourceManager().isInSystemHeader(var->getLocation())) + return ACC_bottom; + + return ACC_plusZero; } // Nothing else. @@ -3421,7 +3366,7 @@ static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr, ObjCInterfaceDecl *CastClass = InterfacePointerType->getObjectType()->getInterface(); if ((CastClass == ExprClass) || - (CastClass && ExprClass->isSuperClassOf(CastClass))) + (CastClass && CastClass->isSuperClassOf(ExprClass))) return true; if (warn) S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge) @@ -3444,12 +3389,13 @@ static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr, return false; } } + } else if (!castType->isObjCIdType()) { + S.Diag(castExpr->getLocStart(), diag::err_objc_cf_bridged_not_interface) + << castExpr->getType() << Parm; + S.Diag(TDNDecl->getLocStart(), diag::note_declared_at); + if (Target) + S.Diag(Target->getLocStart(), diag::note_declared_at); } - S.Diag(castExpr->getLocStart(), diag::err_objc_cf_bridged_not_interface) - << castExpr->getType() << Parm; - S.Diag(TDNDecl->getLocStart(), diag::note_declared_at); - if (Target) - S.Diag(Target->getLocStart(), diag::note_declared_at); return true; } return false; @@ -3469,6 +3415,9 @@ static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr, if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) { if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) { HadTheAttribute = true; + if (Parm->isStr("id")) + return true; + NamedDecl *Target = nullptr; // Check for an existing type with this name. LookupResult R(S, DeclarationName(Parm), SourceLocation(), |