summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaExprObjC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaExprObjC.cpp')
-rw-r--r--lib/Sema/SemaExprObjC.cpp183
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(),
OpenPOWER on IntegriCloud