summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExprObjC.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:01 +0000
commit486754660bb926339aefcf012a3f848592babb8b (patch)
treeecdbc446c9876f4f120f701c243373cd3cb43db3 /lib/Sema/SemaExprObjC.cpp
parent55e6d896ad333f07bb3b1ba487df214fc268a4ab (diff)
Notes
Diffstat (limited to 'lib/Sema/SemaExprObjC.cpp')
-rw-r--r--lib/Sema/SemaExprObjC.cpp76
1 files changed, 45 insertions, 31 deletions
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index cd0c2c47ae4c..bf0ffeba06b2 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -141,7 +141,7 @@ ExprResult Sema::BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S){
return new (Context) ObjCStringLiteral(S, Ty, AtLoc);
}
-/// \brief Emits an error if the given method does not exist, or if the return
+/// Emits an error if the given method does not exist, or if the return
/// type is not an Objective-C object.
static bool validateBoxingMethod(Sema &S, SourceLocation Loc,
const ObjCInterfaceDecl *Class,
@@ -165,7 +165,7 @@ static bool validateBoxingMethod(Sema &S, SourceLocation Loc,
return true;
}
-/// \brief Maps ObjCLiteralKind to NSClassIdKindKind
+/// Maps ObjCLiteralKind to NSClassIdKindKind
static NSAPI::NSClassIdKindKind ClassKindFromLiteralKind(
Sema::ObjCLiteralKind LiteralKind) {
switch (LiteralKind) {
@@ -189,7 +189,7 @@ static NSAPI::NSClassIdKindKind ClassKindFromLiteralKind(
llvm_unreachable("LiteralKind can't be converted into a ClassKind");
}
-/// \brief Validates ObjCInterfaceDecl availability.
+/// Validates ObjCInterfaceDecl availability.
/// ObjCInterfaceDecl, used to create ObjC literals, should be defined
/// if clang not in a debugger mode.
static bool ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl,
@@ -211,7 +211,7 @@ static bool ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl,
return true;
}
-/// \brief Looks up ObjCInterfaceDecl of a given NSClassIdKindKind.
+/// Looks up ObjCInterfaceDecl of a given NSClassIdKindKind.
/// Used to create ObjC literals, such as NSDictionary (@{}),
/// NSArray (@[]) and Boxed Expressions (@())
static ObjCInterfaceDecl *LookupObjCInterfaceDeclForLiteral(Sema &S,
@@ -236,7 +236,7 @@ static ObjCInterfaceDecl *LookupObjCInterfaceDeclForLiteral(Sema &S,
return ID;
}
-/// \brief Retrieve the NSNumber factory method that should be used to create
+/// Retrieve the NSNumber factory method that should be used to create
/// an Objective-C literal for the given type.
static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc,
QualType NumberType,
@@ -379,7 +379,7 @@ ExprResult Sema::ActOnObjCBoolLiteral(SourceLocation AtLoc,
return BuildObjCNumericLiteral(AtLoc, Inner.get());
}
-/// \brief Check that the given expression is a valid element of an Objective-C
+/// Check that the given expression is a valid element of an Objective-C
/// collection literal.
static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element,
QualType T,
@@ -1357,6 +1357,11 @@ QualType Sema::getMessageSendResultType(QualType ReceiverType,
if (isClassMessage)
return resultType;
+ // There is nothing left to do if the result type cannot have a nullability
+ // specifier.
+ if (!resultType->canHaveNullability())
+ return resultType;
+
// Map the nullability of the result into a table index.
unsigned receiverNullabilityIdx = 0;
if (auto nullability = ReceiverType->getNullability(Context))
@@ -1613,6 +1618,11 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
ParmVarDecl *param = Method->parameters()[i];
assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
+ if (param->hasAttr<NoEscapeAttr>())
+ if (auto *BE = dyn_cast<BlockExpr>(
+ argExpr->IgnoreParenNoopCasts(Context)))
+ BE->getBlockDecl()->setDoesNotEscape();
+
// Strip the unbridged-cast placeholder expression off unless it's
// a consumed argument.
if (argExpr->hasPlaceholderType(BuiltinType::ARCUnbridgedCast) &&
@@ -2319,7 +2329,7 @@ static void checkFoundationAPI(Sema &S, SourceLocation Loc,
}
}
-/// \brief Diagnose use of %s directive in an NSString which is being passed
+/// Diagnose use of %s directive in an NSString which is being passed
/// as formatting string to formatting method.
static void
DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S,
@@ -2358,7 +2368,7 @@ DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S,
}
}
-/// \brief Build an Objective-C class message expression.
+/// Build an Objective-C class message expression.
///
/// This routine takes care of both normal class messages and
/// class messages to the superclass.
@@ -2403,11 +2413,12 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
<< FixItHint::CreateInsertion(Loc, "[");
LBracLoc = Loc;
}
- SourceLocation SelLoc;
+ ArrayRef<SourceLocation> SelectorSlotLocs;
if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
- SelLoc = SelectorLocs.front();
+ SelectorSlotLocs = SelectorLocs;
else
- SelLoc = Loc;
+ SelectorSlotLocs = Loc;
+ SourceLocation SelLoc = SelectorSlotLocs.front();
if (ReceiverType->isDependentType()) {
// If the receiver type is dependent, we can't type-check anything
@@ -2432,7 +2443,7 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
assert(Class && "We don't know which class we're messaging?");
// objc++ diagnoses during typename annotation.
if (!getLangOpts().CPlusPlus)
- (void)DiagnoseUseOfDecl(Class, SelLoc);
+ (void)DiagnoseUseOfDecl(Class, SelectorSlotLocs);
// Find the method we are messaging.
if (!Method) {
SourceRange TypeRange
@@ -2457,7 +2468,7 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
if (!Method)
Method = Class->lookupPrivateClassMethod(Sel);
- if (Method && DiagnoseUseOfDecl(Method, SelLoc))
+ if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs))
return ExprError();
}
@@ -2581,7 +2592,7 @@ static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M) {
return false;
}
-/// \brief Build an Objective-C instance message expression.
+/// Build an Objective-C instance message expression.
///
/// This routine takes care of both normal instance messages and
/// instance messages to the superclass instance.
@@ -2627,11 +2638,12 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
SourceLocation Loc = SuperLoc.isValid()? SuperLoc : Receiver->getLocStart();
SourceRange RecRange =
SuperLoc.isValid()? SuperLoc : Receiver->getSourceRange();
- SourceLocation SelLoc;
+ ArrayRef<SourceLocation> SelectorSlotLocs;
if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
- SelLoc = SelectorLocs.front();
+ SelectorSlotLocs = SelectorLocs;
else
- SelLoc = Loc;
+ SelectorSlotLocs = Loc;
+ SourceLocation SelLoc = SelectorSlotLocs.front();
if (LBracLoc.isInvalid()) {
Diag(Loc, diag::err_missing_open_square_message_send)
@@ -2743,7 +2755,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
if (!AreMultipleMethodsInGlobalPool(Sel, Method,
SourceRange(LBracLoc, RBracLoc),
receiverIsIdLike, Methods))
- DiagnoseUseOfDecl(Method, SelLoc);
+ DiagnoseUseOfDecl(Method, SelectorSlotLocs);
}
} else if (ReceiverType->isObjCClassOrClassKindOfType() ||
ReceiverType->isObjCQualifiedClassType()) {
@@ -2775,7 +2787,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
if (!Method)
Method = ClassDecl->lookupPrivateClassMethod(Sel);
}
- if (Method && DiagnoseUseOfDecl(Method, SelLoc))
+ if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs))
return ExprError();
}
if (!Method) {
@@ -2792,7 +2804,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
// to select a better one.
Method = Methods[0];
- // If we find an instance method, emit waring.
+ // If we find an instance method, emit warning.
if (Method->isInstanceMethod()) {
if (const ObjCInterfaceDecl *ID =
dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
@@ -2822,7 +2834,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
Method = LookupMethodInQualifiedType(Sel, QIdTy, true);
if (!Method)
Method = LookupMethodInQualifiedType(Sel, QIdTy, false);
- if (Method && DiagnoseUseOfDecl(Method, SelLoc))
+ if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs))
return ExprError();
} else if (const ObjCObjectPointerType *OCIType
= ReceiverType->getAsObjCInterfacePointerType()) {
@@ -2897,7 +2909,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
}
}
}
- if (Method && DiagnoseUseOfDecl(Method, SelLoc, forwardClass))
+ if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs, forwardClass))
return ExprError();
} else {
// Reject other random receiver types (e.g. structs).
@@ -3491,6 +3503,7 @@ static void addFixitForObjCARCConversion(Sema &S,
// We handle C-style and implicit casts here.
switch (CCK) {
case Sema::CCK_ImplicitConversion:
+ case Sema::CCK_ForBuiltinOverloadedOp:
case Sema::CCK_CStyleCast:
case Sema::CCK_OtherCast:
break;
@@ -3644,11 +3657,13 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
SourceLocation afterLParen = S.getLocForEndOfToken(castRange.getBegin());
SourceLocation noteLoc = afterLParen.isValid() ? afterLParen : loc;
+ unsigned convKindForDiag = Sema::isCast(CCK) ? 0 : 1;
+
// Bridge from an ARC type to a CF type.
if (castACTC == ACTC_retainable && isAnyRetainable(exprACTC)) {
S.Diag(loc, diag::err_arc_cast_requires_bridge)
- << unsigned(CCK == Sema::CCK_ImplicitConversion) // cast|implicit
+ << convKindForDiag
<< 2 // of C pointer type
<< castExprType
<< unsigned(castType->isBlockPointerType()) // to ObjC|block type
@@ -3690,7 +3705,7 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC)) {
bool br = S.isKnownName("CFBridgingRetain");
S.Diag(loc, diag::err_arc_cast_requires_bridge)
- << unsigned(CCK == Sema::CCK_ImplicitConversion) // cast|implicit
+ << convKindForDiag
<< unsigned(castExprType->isBlockPointerType()) // of ObjC|block type
<< castExprType
<< 2 // to C pointer type
@@ -3727,7 +3742,7 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
}
S.Diag(loc, diag::err_arc_mismatched_cast)
- << (CCK != Sema::CCK_ImplicitConversion)
+ << !convKindForDiag
<< srcKind << castExprType << castType
<< castRange << castExpr->getSourceRange();
}
@@ -4180,7 +4195,7 @@ Sema::CheckObjCConversion(SourceRange castRange, QualType castType,
if (exprACTC == ACTC_indirectRetainable && castACTC == ACTC_voidPtr)
return ACR_okay;
if (castACTC == ACTC_indirectRetainable && exprACTC == ACTC_voidPtr &&
- CCK != CCK_ImplicitConversion)
+ isCast(CCK))
return ACR_okay;
switch (ARCCastChecker(Context, exprACTC, castACTC, false).Visit(castExpr)) {
@@ -4205,8 +4220,7 @@ Sema::CheckObjCConversion(SourceRange castRange, QualType castType,
// If this is a non-implicit cast from id or block type to a
// CoreFoundation type, delay complaining in case the cast is used
// in an acceptable context.
- if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC) &&
- CCK != CCK_ImplicitConversion)
+ if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC) && isCast(CCK))
return ACR_unbridged;
// Issue a diagnostic about a missing @-sign when implicit casting a cstring
@@ -4276,9 +4290,9 @@ Expr *Sema::stripARCUnbridgedCast(Expr *e) {
} else if (UnaryOperator *uo = dyn_cast<UnaryOperator>(e)) {
assert(uo->getOpcode() == UO_Extension);
Expr *sub = stripARCUnbridgedCast(uo->getSubExpr());
- return new (Context) UnaryOperator(sub, UO_Extension, sub->getType(),
- sub->getValueKind(), sub->getObjectKind(),
- uo->getOperatorLoc());
+ return new (Context)
+ UnaryOperator(sub, UO_Extension, sub->getType(), sub->getValueKind(),
+ sub->getObjectKind(), uo->getOperatorLoc(), false);
} else if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {
assert(!gse->isResultDependent());