1 //===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements semantic analysis for Objective-C expressions.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "clang/AST/ASTContext.h"
14 #include "clang/AST/DeclObjC.h"
15 #include "clang/AST/ExprObjC.h"
16 #include "clang/AST/StmtVisitor.h"
17 #include "clang/AST/TypeLoc.h"
18 #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
19 #include "clang/Basic/Builtins.h"
20 #include "clang/Edit/Commit.h"
21 #include "clang/Edit/Rewriters.h"
22 #include "clang/Lex/Preprocessor.h"
23 #include "clang/Sema/Initialization.h"
24 #include "clang/Sema/Lookup.h"
25 #include "clang/Sema/Scope.h"
26 #include "clang/Sema/ScopeInfo.h"
27 #include "clang/Sema/SemaInternal.h"
28 #include "llvm/ADT/SmallString.h"
29 #include "llvm/Support/ConvertUTF.h"
30 #include <optional>
31
32 using namespace clang;
33 using namespace sema;
34 using llvm::ArrayRef;
35
ParseObjCStringLiteral(SourceLocation * AtLocs,ArrayRef<Expr * > Strings)36 ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
37 ArrayRef<Expr *> Strings) {
38 // Most ObjC strings are formed out of a single piece. However, we *can*
39 // have strings formed out of multiple @ strings with multiple pptokens in
40 // each one, e.g. @"foo" "bar" @"baz" "qux" which need to be turned into one
41 // StringLiteral for ObjCStringLiteral to hold onto.
42 StringLiteral *S = cast<StringLiteral>(Strings[0]);
43
44 // If we have a multi-part string, merge it all together.
45 if (Strings.size() != 1) {
46 // Concatenate objc strings.
47 SmallString<128> StrBuf;
48 SmallVector<SourceLocation, 8> StrLocs;
49
50 for (Expr *E : Strings) {
51 S = cast<StringLiteral>(E);
52
53 // ObjC strings can't be wide or UTF.
54 if (!S->isOrdinary()) {
55 Diag(S->getBeginLoc(), diag::err_cfstring_literal_not_string_constant)
56 << S->getSourceRange();
57 return true;
58 }
59
60 // Append the string.
61 StrBuf += S->getString();
62
63 // Get the locations of the string tokens.
64 StrLocs.append(S->tokloc_begin(), S->tokloc_end());
65 }
66
67 // Create the aggregate string with the appropriate content and location
68 // information.
69 const ConstantArrayType *CAT = Context.getAsConstantArrayType(S->getType());
70 assert(CAT && "String literal not of constant array type!");
71 QualType StrTy = Context.getConstantArrayType(
72 CAT->getElementType(), llvm::APInt(32, StrBuf.size() + 1), nullptr,
73 CAT->getSizeModifier(), CAT->getIndexTypeCVRQualifiers());
74 S = StringLiteral::Create(Context, StrBuf, StringLiteral::Ordinary,
75 /*Pascal=*/false, StrTy, &StrLocs[0],
76 StrLocs.size());
77 }
78
79 return BuildObjCStringLiteral(AtLocs[0], S);
80 }
81
BuildObjCStringLiteral(SourceLocation AtLoc,StringLiteral * S)82 ExprResult Sema::BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S){
83 // Verify that this composite string is acceptable for ObjC strings.
84 if (CheckObjCString(S))
85 return true;
86
87 // Initialize the constant string interface lazily. This assumes
88 // the NSString interface is seen in this translation unit. Note: We
89 // don't use NSConstantString, since the runtime team considers this
90 // interface private (even though it appears in the header files).
91 QualType Ty = Context.getObjCConstantStringInterface();
92 if (!Ty.isNull()) {
93 Ty = Context.getObjCObjectPointerType(Ty);
94 } else if (getLangOpts().NoConstantCFStrings) {
95 IdentifierInfo *NSIdent=nullptr;
96 std::string StringClass(getLangOpts().ObjCConstantStringClass);
97
98 if (StringClass.empty())
99 NSIdent = &Context.Idents.get("NSConstantString");
100 else
101 NSIdent = &Context.Idents.get(StringClass);
102
103 NamedDecl *IF = LookupSingleName(TUScope, NSIdent, AtLoc,
104 LookupOrdinaryName);
105 if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
106 Context.setObjCConstantStringInterface(StrIF);
107 Ty = Context.getObjCConstantStringInterface();
108 Ty = Context.getObjCObjectPointerType(Ty);
109 } else {
110 // If there is no NSConstantString interface defined then treat this
111 // as error and recover from it.
112 Diag(S->getBeginLoc(), diag::err_no_nsconstant_string_class)
113 << NSIdent << S->getSourceRange();
114 Ty = Context.getObjCIdType();
115 }
116 } else {
117 IdentifierInfo *NSIdent = NSAPIObj->getNSClassId(NSAPI::ClassId_NSString);
118 NamedDecl *IF = LookupSingleName(TUScope, NSIdent, AtLoc,
119 LookupOrdinaryName);
120 if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
121 Context.setObjCConstantStringInterface(StrIF);
122 Ty = Context.getObjCConstantStringInterface();
123 Ty = Context.getObjCObjectPointerType(Ty);
124 } else {
125 // If there is no NSString interface defined, implicitly declare
126 // a @class NSString; and use that instead. This is to make sure
127 // type of an NSString literal is represented correctly, instead of
128 // being an 'id' type.
129 Ty = Context.getObjCNSStringType();
130 if (Ty.isNull()) {
131 ObjCInterfaceDecl *NSStringIDecl =
132 ObjCInterfaceDecl::Create (Context,
133 Context.getTranslationUnitDecl(),
134 SourceLocation(), NSIdent,
135 nullptr, nullptr, SourceLocation());
136 Ty = Context.getObjCInterfaceType(NSStringIDecl);
137 Context.setObjCNSStringType(Ty);
138 }
139 Ty = Context.getObjCObjectPointerType(Ty);
140 }
141 }
142
143 return new (Context) ObjCStringLiteral(S, Ty, AtLoc);
144 }
145
146 /// Emits an error if the given method does not exist, or if the return
147 /// type is not an Objective-C object.
validateBoxingMethod(Sema & S,SourceLocation Loc,const ObjCInterfaceDecl * Class,Selector Sel,const ObjCMethodDecl * Method)148 static bool validateBoxingMethod(Sema &S, SourceLocation Loc,
149 const ObjCInterfaceDecl *Class,
150 Selector Sel, const ObjCMethodDecl *Method) {
151 if (!Method) {
152 // FIXME: Is there a better way to avoid quotes than using getName()?
153 S.Diag(Loc, diag::err_undeclared_boxing_method) << Sel << Class->getName();
154 return false;
155 }
156
157 // Make sure the return type is reasonable.
158 QualType ReturnType = Method->getReturnType();
159 if (!ReturnType->isObjCObjectPointerType()) {
160 S.Diag(Loc, diag::err_objc_literal_method_sig)
161 << Sel;
162 S.Diag(Method->getLocation(), diag::note_objc_literal_method_return)
163 << ReturnType;
164 return false;
165 }
166
167 return true;
168 }
169
170 /// Maps ObjCLiteralKind to NSClassIdKindKind
ClassKindFromLiteralKind(Sema::ObjCLiteralKind LiteralKind)171 static NSAPI::NSClassIdKindKind ClassKindFromLiteralKind(
172 Sema::ObjCLiteralKind LiteralKind) {
173 switch (LiteralKind) {
174 case Sema::LK_Array:
175 return NSAPI::ClassId_NSArray;
176 case Sema::LK_Dictionary:
177 return NSAPI::ClassId_NSDictionary;
178 case Sema::LK_Numeric:
179 return NSAPI::ClassId_NSNumber;
180 case Sema::LK_String:
181 return NSAPI::ClassId_NSString;
182 case Sema::LK_Boxed:
183 return NSAPI::ClassId_NSValue;
184
185 // there is no corresponding matching
186 // between LK_None/LK_Block and NSClassIdKindKind
187 case Sema::LK_Block:
188 case Sema::LK_None:
189 break;
190 }
191 llvm_unreachable("LiteralKind can't be converted into a ClassKind");
192 }
193
194 /// Validates ObjCInterfaceDecl availability.
195 /// ObjCInterfaceDecl, used to create ObjC literals, should be defined
196 /// if clang not in a debugger mode.
ValidateObjCLiteralInterfaceDecl(Sema & S,ObjCInterfaceDecl * Decl,SourceLocation Loc,Sema::ObjCLiteralKind LiteralKind)197 static bool ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl,
198 SourceLocation Loc,
199 Sema::ObjCLiteralKind LiteralKind) {
200 if (!Decl) {
201 NSAPI::NSClassIdKindKind Kind = ClassKindFromLiteralKind(LiteralKind);
202 IdentifierInfo *II = S.NSAPIObj->getNSClassId(Kind);
203 S.Diag(Loc, diag::err_undeclared_objc_literal_class)
204 << II->getName() << LiteralKind;
205 return false;
206 } else if (!Decl->hasDefinition() && !S.getLangOpts().DebuggerObjCLiteral) {
207 S.Diag(Loc, diag::err_undeclared_objc_literal_class)
208 << Decl->getName() << LiteralKind;
209 S.Diag(Decl->getLocation(), diag::note_forward_class);
210 return false;
211 }
212
213 return true;
214 }
215
216 /// Looks up ObjCInterfaceDecl of a given NSClassIdKindKind.
217 /// Used to create ObjC literals, such as NSDictionary (@{}),
218 /// NSArray (@[]) and Boxed Expressions (@())
LookupObjCInterfaceDeclForLiteral(Sema & S,SourceLocation Loc,Sema::ObjCLiteralKind LiteralKind)219 static ObjCInterfaceDecl *LookupObjCInterfaceDeclForLiteral(Sema &S,
220 SourceLocation Loc,
221 Sema::ObjCLiteralKind LiteralKind) {
222 NSAPI::NSClassIdKindKind ClassKind = ClassKindFromLiteralKind(LiteralKind);
223 IdentifierInfo *II = S.NSAPIObj->getNSClassId(ClassKind);
224 NamedDecl *IF = S.LookupSingleName(S.TUScope, II, Loc,
225 Sema::LookupOrdinaryName);
226 ObjCInterfaceDecl *ID = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
227 if (!ID && S.getLangOpts().DebuggerObjCLiteral) {
228 ASTContext &Context = S.Context;
229 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
230 ID = ObjCInterfaceDecl::Create (Context, TU, SourceLocation(), II,
231 nullptr, nullptr, SourceLocation());
232 }
233
234 if (!ValidateObjCLiteralInterfaceDecl(S, ID, Loc, LiteralKind)) {
235 ID = nullptr;
236 }
237
238 return ID;
239 }
240
241 /// Retrieve the NSNumber factory method that should be used to create
242 /// an Objective-C literal for the given type.
getNSNumberFactoryMethod(Sema & S,SourceLocation Loc,QualType NumberType,bool isLiteral=false,SourceRange R=SourceRange ())243 static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc,
244 QualType NumberType,
245 bool isLiteral = false,
246 SourceRange R = SourceRange()) {
247 std::optional<NSAPI::NSNumberLiteralMethodKind> Kind =
248 S.NSAPIObj->getNSNumberFactoryMethodKind(NumberType);
249
250 if (!Kind) {
251 if (isLiteral) {
252 S.Diag(Loc, diag::err_invalid_nsnumber_type)
253 << NumberType << R;
254 }
255 return nullptr;
256 }
257
258 // If we already looked up this method, we're done.
259 if (S.NSNumberLiteralMethods[*Kind])
260 return S.NSNumberLiteralMethods[*Kind];
261
262 Selector Sel = S.NSAPIObj->getNSNumberLiteralSelector(*Kind,
263 /*Instance=*/false);
264
265 ASTContext &CX = S.Context;
266
267 // Look up the NSNumber class, if we haven't done so already. It's cached
268 // in the Sema instance.
269 if (!S.NSNumberDecl) {
270 S.NSNumberDecl = LookupObjCInterfaceDeclForLiteral(S, Loc,
271 Sema::LK_Numeric);
272 if (!S.NSNumberDecl) {
273 return nullptr;
274 }
275 }
276
277 if (S.NSNumberPointer.isNull()) {
278 // generate the pointer to NSNumber type.
279 QualType NSNumberObject = CX.getObjCInterfaceType(S.NSNumberDecl);
280 S.NSNumberPointer = CX.getObjCObjectPointerType(NSNumberObject);
281 }
282
283 // Look for the appropriate method within NSNumber.
284 ObjCMethodDecl *Method = S.NSNumberDecl->lookupClassMethod(Sel);
285 if (!Method && S.getLangOpts().DebuggerObjCLiteral) {
286 // create a stub definition this NSNumber factory method.
287 TypeSourceInfo *ReturnTInfo = nullptr;
288 Method =
289 ObjCMethodDecl::Create(CX, SourceLocation(), SourceLocation(), Sel,
290 S.NSNumberPointer, ReturnTInfo, S.NSNumberDecl,
291 /*isInstance=*/false, /*isVariadic=*/false,
292 /*isPropertyAccessor=*/false,
293 /*isSynthesizedAccessorStub=*/false,
294 /*isImplicitlyDeclared=*/true,
295 /*isDefined=*/false, ObjCMethodDecl::Required,
296 /*HasRelatedResultType=*/false);
297 ParmVarDecl *value = ParmVarDecl::Create(S.Context, Method,
298 SourceLocation(), SourceLocation(),
299 &CX.Idents.get("value"),
300 NumberType, /*TInfo=*/nullptr,
301 SC_None, nullptr);
302 Method->setMethodParams(S.Context, value, std::nullopt);
303 }
304
305 if (!validateBoxingMethod(S, Loc, S.NSNumberDecl, Sel, Method))
306 return nullptr;
307
308 // Note: if the parameter type is out-of-line, we'll catch it later in the
309 // implicit conversion.
310
311 S.NSNumberLiteralMethods[*Kind] = Method;
312 return Method;
313 }
314
315 /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the
316 /// numeric literal expression. Type of the expression will be "NSNumber *".
BuildObjCNumericLiteral(SourceLocation AtLoc,Expr * Number)317 ExprResult Sema::BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number) {
318 // Determine the type of the literal.
319 QualType NumberType = Number->getType();
320 if (CharacterLiteral *Char = dyn_cast<CharacterLiteral>(Number)) {
321 // In C, character literals have type 'int'. That's not the type we want
322 // to use to determine the Objective-c literal kind.
323 switch (Char->getKind()) {
324 case CharacterLiteral::Ascii:
325 case CharacterLiteral::UTF8:
326 NumberType = Context.CharTy;
327 break;
328
329 case CharacterLiteral::Wide:
330 NumberType = Context.getWideCharType();
331 break;
332
333 case CharacterLiteral::UTF16:
334 NumberType = Context.Char16Ty;
335 break;
336
337 case CharacterLiteral::UTF32:
338 NumberType = Context.Char32Ty;
339 break;
340 }
341 }
342
343 // Look for the appropriate method within NSNumber.
344 // Construct the literal.
345 SourceRange NR(Number->getSourceRange());
346 ObjCMethodDecl *Method = getNSNumberFactoryMethod(*this, AtLoc, NumberType,
347 true, NR);
348 if (!Method)
349 return ExprError();
350
351 // Convert the number to the type that the parameter expects.
352 ParmVarDecl *ParamDecl = Method->parameters()[0];
353 InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
354 ParamDecl);
355 ExprResult ConvertedNumber = PerformCopyInitialization(Entity,
356 SourceLocation(),
357 Number);
358 if (ConvertedNumber.isInvalid())
359 return ExprError();
360 Number = ConvertedNumber.get();
361
362 // Use the effective source range of the literal, including the leading '@'.
363 return MaybeBindToTemporary(
364 new (Context) ObjCBoxedExpr(Number, NSNumberPointer, Method,
365 SourceRange(AtLoc, NR.getEnd())));
366 }
367
ActOnObjCBoolLiteral(SourceLocation AtLoc,SourceLocation ValueLoc,bool Value)368 ExprResult Sema::ActOnObjCBoolLiteral(SourceLocation AtLoc,
369 SourceLocation ValueLoc,
370 bool Value) {
371 ExprResult Inner;
372 if (getLangOpts().CPlusPlus) {
373 Inner = ActOnCXXBoolLiteral(ValueLoc, Value? tok::kw_true : tok::kw_false);
374 } else {
375 // C doesn't actually have a way to represent literal values of type
376 // _Bool. So, we'll use 0/1 and implicit cast to _Bool.
377 Inner = ActOnIntegerConstant(ValueLoc, Value? 1 : 0);
378 Inner = ImpCastExprToType(Inner.get(), Context.BoolTy,
379 CK_IntegralToBoolean);
380 }
381
382 return BuildObjCNumericLiteral(AtLoc, Inner.get());
383 }
384
385 /// Check that the given expression is a valid element of an Objective-C
386 /// collection literal.
CheckObjCCollectionLiteralElement(Sema & S,Expr * Element,QualType T,bool ArrayLiteral=false)387 static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element,
388 QualType T,
389 bool ArrayLiteral = false) {
390 // If the expression is type-dependent, there's nothing for us to do.
391 if (Element->isTypeDependent())
392 return Element;
393
394 ExprResult Result = S.CheckPlaceholderExpr(Element);
395 if (Result.isInvalid())
396 return ExprError();
397 Element = Result.get();
398
399 // In C++, check for an implicit conversion to an Objective-C object pointer
400 // type.
401 if (S.getLangOpts().CPlusPlus && Element->getType()->isRecordType()) {
402 InitializedEntity Entity
403 = InitializedEntity::InitializeParameter(S.Context, T,
404 /*Consumed=*/false);
405 InitializationKind Kind = InitializationKind::CreateCopy(
406 Element->getBeginLoc(), SourceLocation());
407 InitializationSequence Seq(S, Entity, Kind, Element);
408 if (!Seq.Failed())
409 return Seq.Perform(S, Entity, Kind, Element);
410 }
411
412 Expr *OrigElement = Element;
413
414 // Perform lvalue-to-rvalue conversion.
415 Result = S.DefaultLvalueConversion(Element);
416 if (Result.isInvalid())
417 return ExprError();
418 Element = Result.get();
419
420 // Make sure that we have an Objective-C pointer type or block.
421 if (!Element->getType()->isObjCObjectPointerType() &&
422 !Element->getType()->isBlockPointerType()) {
423 bool Recovered = false;
424
425 // If this is potentially an Objective-C numeric literal, add the '@'.
426 if (isa<IntegerLiteral>(OrigElement) ||
427 isa<CharacterLiteral>(OrigElement) ||
428 isa<FloatingLiteral>(OrigElement) ||
429 isa<ObjCBoolLiteralExpr>(OrigElement) ||
430 isa<CXXBoolLiteralExpr>(OrigElement)) {
431 if (S.NSAPIObj->getNSNumberFactoryMethodKind(OrigElement->getType())) {
432 int Which = isa<CharacterLiteral>(OrigElement) ? 1
433 : (isa<CXXBoolLiteralExpr>(OrigElement) ||
434 isa<ObjCBoolLiteralExpr>(OrigElement)) ? 2
435 : 3;
436
437 S.Diag(OrigElement->getBeginLoc(), diag::err_box_literal_collection)
438 << Which << OrigElement->getSourceRange()
439 << FixItHint::CreateInsertion(OrigElement->getBeginLoc(), "@");
440
441 Result =
442 S.BuildObjCNumericLiteral(OrigElement->getBeginLoc(), OrigElement);
443 if (Result.isInvalid())
444 return ExprError();
445
446 Element = Result.get();
447 Recovered = true;
448 }
449 }
450 // If this is potentially an Objective-C string literal, add the '@'.
451 else if (StringLiteral *String = dyn_cast<StringLiteral>(OrigElement)) {
452 if (String->isOrdinary()) {
453 S.Diag(OrigElement->getBeginLoc(), diag::err_box_literal_collection)
454 << 0 << OrigElement->getSourceRange()
455 << FixItHint::CreateInsertion(OrigElement->getBeginLoc(), "@");
456
457 Result = S.BuildObjCStringLiteral(OrigElement->getBeginLoc(), String);
458 if (Result.isInvalid())
459 return ExprError();
460
461 Element = Result.get();
462 Recovered = true;
463 }
464 }
465
466 if (!Recovered) {
467 S.Diag(Element->getBeginLoc(), diag::err_invalid_collection_element)
468 << Element->getType();
469 return ExprError();
470 }
471 }
472 if (ArrayLiteral)
473 if (ObjCStringLiteral *getString =
474 dyn_cast<ObjCStringLiteral>(OrigElement)) {
475 if (StringLiteral *SL = getString->getString()) {
476 unsigned numConcat = SL->getNumConcatenated();
477 if (numConcat > 1) {
478 // Only warn if the concatenated string doesn't come from a macro.
479 bool hasMacro = false;
480 for (unsigned i = 0; i < numConcat ; ++i)
481 if (SL->getStrTokenLoc(i).isMacroID()) {
482 hasMacro = true;
483 break;
484 }
485 if (!hasMacro)
486 S.Diag(Element->getBeginLoc(),
487 diag::warn_concatenated_nsarray_literal)
488 << Element->getType();
489 }
490 }
491 }
492
493 // Make sure that the element has the type that the container factory
494 // function expects.
495 return S.PerformCopyInitialization(
496 InitializedEntity::InitializeParameter(S.Context, T,
497 /*Consumed=*/false),
498 Element->getBeginLoc(), Element);
499 }
500
BuildObjCBoxedExpr(SourceRange SR,Expr * ValueExpr)501 ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
502 if (ValueExpr->isTypeDependent()) {
503 ObjCBoxedExpr *BoxedExpr =
504 new (Context) ObjCBoxedExpr(ValueExpr, Context.DependentTy, nullptr, SR);
505 return BoxedExpr;
506 }
507 ObjCMethodDecl *BoxingMethod = nullptr;
508 QualType BoxedType;
509 // Convert the expression to an RValue, so we can check for pointer types...
510 ExprResult RValue = DefaultFunctionArrayLvalueConversion(ValueExpr);
511 if (RValue.isInvalid()) {
512 return ExprError();
513 }
514 SourceLocation Loc = SR.getBegin();
515 ValueExpr = RValue.get();
516 QualType ValueType(ValueExpr->getType());
517 if (const PointerType *PT = ValueType->getAs<PointerType>()) {
518 QualType PointeeType = PT->getPointeeType();
519 if (Context.hasSameUnqualifiedType(PointeeType, Context.CharTy)) {
520
521 if (!NSStringDecl) {
522 NSStringDecl = LookupObjCInterfaceDeclForLiteral(*this, Loc,
523 Sema::LK_String);
524 if (!NSStringDecl) {
525 return ExprError();
526 }
527 QualType NSStringObject = Context.getObjCInterfaceType(NSStringDecl);
528 NSStringPointer = Context.getObjCObjectPointerType(NSStringObject);
529 }
530
531 // The boxed expression can be emitted as a compile time constant if it is
532 // a string literal whose character encoding is compatible with UTF-8.
533 if (auto *CE = dyn_cast<ImplicitCastExpr>(ValueExpr))
534 if (CE->getCastKind() == CK_ArrayToPointerDecay)
535 if (auto *SL =
536 dyn_cast<StringLiteral>(CE->getSubExpr()->IgnoreParens())) {
537 assert((SL->isOrdinary() || SL->isUTF8()) &&
538 "unexpected character encoding");
539 StringRef Str = SL->getString();
540 const llvm::UTF8 *StrBegin = Str.bytes_begin();
541 const llvm::UTF8 *StrEnd = Str.bytes_end();
542 // Check that this is a valid UTF-8 string.
543 if (llvm::isLegalUTF8String(&StrBegin, StrEnd)) {
544 BoxedType = Context.getAttributedType(
545 AttributedType::getNullabilityAttrKind(
546 NullabilityKind::NonNull),
547 NSStringPointer, NSStringPointer);
548 return new (Context) ObjCBoxedExpr(CE, BoxedType, nullptr, SR);
549 }
550
551 Diag(SL->getBeginLoc(), diag::warn_objc_boxing_invalid_utf8_string)
552 << NSStringPointer << SL->getSourceRange();
553 }
554
555 if (!StringWithUTF8StringMethod) {
556 IdentifierInfo *II = &Context.Idents.get("stringWithUTF8String");
557 Selector stringWithUTF8String = Context.Selectors.getUnarySelector(II);
558
559 // Look for the appropriate method within NSString.
560 BoxingMethod = NSStringDecl->lookupClassMethod(stringWithUTF8String);
561 if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) {
562 // Debugger needs to work even if NSString hasn't been defined.
563 TypeSourceInfo *ReturnTInfo = nullptr;
564 ObjCMethodDecl *M = ObjCMethodDecl::Create(
565 Context, SourceLocation(), SourceLocation(), stringWithUTF8String,
566 NSStringPointer, ReturnTInfo, NSStringDecl,
567 /*isInstance=*/false, /*isVariadic=*/false,
568 /*isPropertyAccessor=*/false,
569 /*isSynthesizedAccessorStub=*/false,
570 /*isImplicitlyDeclared=*/true,
571 /*isDefined=*/false, ObjCMethodDecl::Required,
572 /*HasRelatedResultType=*/false);
573 QualType ConstCharType = Context.CharTy.withConst();
574 ParmVarDecl *value =
575 ParmVarDecl::Create(Context, M,
576 SourceLocation(), SourceLocation(),
577 &Context.Idents.get("value"),
578 Context.getPointerType(ConstCharType),
579 /*TInfo=*/nullptr,
580 SC_None, nullptr);
581 M->setMethodParams(Context, value, std::nullopt);
582 BoxingMethod = M;
583 }
584
585 if (!validateBoxingMethod(*this, Loc, NSStringDecl,
586 stringWithUTF8String, BoxingMethod))
587 return ExprError();
588
589 StringWithUTF8StringMethod = BoxingMethod;
590 }
591
592 BoxingMethod = StringWithUTF8StringMethod;
593 BoxedType = NSStringPointer;
594 // Transfer the nullability from method's return type.
595 std::optional<NullabilityKind> Nullability =
596 BoxingMethod->getReturnType()->getNullability();
597 if (Nullability)
598 BoxedType = Context.getAttributedType(
599 AttributedType::getNullabilityAttrKind(*Nullability), BoxedType,
600 BoxedType);
601 }
602 } else if (ValueType->isBuiltinType()) {
603 // The other types we support are numeric, char and BOOL/bool. We could also
604 // provide limited support for structure types, such as NSRange, NSRect, and
605 // NSSize. See NSValue (NSValueGeometryExtensions) in <Foundation/NSGeometry.h>
606 // for more details.
607
608 // Check for a top-level character literal.
609 if (const CharacterLiteral *Char =
610 dyn_cast<CharacterLiteral>(ValueExpr->IgnoreParens())) {
611 // In C, character literals have type 'int'. That's not the type we want
612 // to use to determine the Objective-c literal kind.
613 switch (Char->getKind()) {
614 case CharacterLiteral::Ascii:
615 case CharacterLiteral::UTF8:
616 ValueType = Context.CharTy;
617 break;
618
619 case CharacterLiteral::Wide:
620 ValueType = Context.getWideCharType();
621 break;
622
623 case CharacterLiteral::UTF16:
624 ValueType = Context.Char16Ty;
625 break;
626
627 case CharacterLiteral::UTF32:
628 ValueType = Context.Char32Ty;
629 break;
630 }
631 }
632 // FIXME: Do I need to do anything special with BoolTy expressions?
633
634 // Look for the appropriate method within NSNumber.
635 BoxingMethod = getNSNumberFactoryMethod(*this, Loc, ValueType);
636 BoxedType = NSNumberPointer;
637 } else if (const EnumType *ET = ValueType->getAs<EnumType>()) {
638 if (!ET->getDecl()->isComplete()) {
639 Diag(Loc, diag::err_objc_incomplete_boxed_expression_type)
640 << ValueType << ValueExpr->getSourceRange();
641 return ExprError();
642 }
643
644 BoxingMethod = getNSNumberFactoryMethod(*this, Loc,
645 ET->getDecl()->getIntegerType());
646 BoxedType = NSNumberPointer;
647 } else if (ValueType->isObjCBoxableRecordType()) {
648 // Support for structure types, that marked as objc_boxable
649 // struct __attribute__((objc_boxable)) s { ... };
650
651 // Look up the NSValue class, if we haven't done so already. It's cached
652 // in the Sema instance.
653 if (!NSValueDecl) {
654 NSValueDecl = LookupObjCInterfaceDeclForLiteral(*this, Loc,
655 Sema::LK_Boxed);
656 if (!NSValueDecl) {
657 return ExprError();
658 }
659
660 // generate the pointer to NSValue type.
661 QualType NSValueObject = Context.getObjCInterfaceType(NSValueDecl);
662 NSValuePointer = Context.getObjCObjectPointerType(NSValueObject);
663 }
664
665 if (!ValueWithBytesObjCTypeMethod) {
666 IdentifierInfo *II[] = {
667 &Context.Idents.get("valueWithBytes"),
668 &Context.Idents.get("objCType")
669 };
670 Selector ValueWithBytesObjCType = Context.Selectors.getSelector(2, II);
671
672 // Look for the appropriate method within NSValue.
673 BoxingMethod = NSValueDecl->lookupClassMethod(ValueWithBytesObjCType);
674 if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) {
675 // Debugger needs to work even if NSValue hasn't been defined.
676 TypeSourceInfo *ReturnTInfo = nullptr;
677 ObjCMethodDecl *M = ObjCMethodDecl::Create(
678 Context, SourceLocation(), SourceLocation(), ValueWithBytesObjCType,
679 NSValuePointer, ReturnTInfo, NSValueDecl,
680 /*isInstance=*/false,
681 /*isVariadic=*/false,
682 /*isPropertyAccessor=*/false,
683 /*isSynthesizedAccessorStub=*/false,
684 /*isImplicitlyDeclared=*/true,
685 /*isDefined=*/false, ObjCMethodDecl::Required,
686 /*HasRelatedResultType=*/false);
687
688 SmallVector<ParmVarDecl *, 2> Params;
689
690 ParmVarDecl *bytes =
691 ParmVarDecl::Create(Context, M,
692 SourceLocation(), SourceLocation(),
693 &Context.Idents.get("bytes"),
694 Context.VoidPtrTy.withConst(),
695 /*TInfo=*/nullptr,
696 SC_None, nullptr);
697 Params.push_back(bytes);
698
699 QualType ConstCharType = Context.CharTy.withConst();
700 ParmVarDecl *type =
701 ParmVarDecl::Create(Context, M,
702 SourceLocation(), SourceLocation(),
703 &Context.Idents.get("type"),
704 Context.getPointerType(ConstCharType),
705 /*TInfo=*/nullptr,
706 SC_None, nullptr);
707 Params.push_back(type);
708
709 M->setMethodParams(Context, Params, std::nullopt);
710 BoxingMethod = M;
711 }
712
713 if (!validateBoxingMethod(*this, Loc, NSValueDecl,
714 ValueWithBytesObjCType, BoxingMethod))
715 return ExprError();
716
717 ValueWithBytesObjCTypeMethod = BoxingMethod;
718 }
719
720 if (!ValueType.isTriviallyCopyableType(Context)) {
721 Diag(Loc, diag::err_objc_non_trivially_copyable_boxed_expression_type)
722 << ValueType << ValueExpr->getSourceRange();
723 return ExprError();
724 }
725
726 BoxingMethod = ValueWithBytesObjCTypeMethod;
727 BoxedType = NSValuePointer;
728 }
729
730 if (!BoxingMethod) {
731 Diag(Loc, diag::err_objc_illegal_boxed_expression_type)
732 << ValueType << ValueExpr->getSourceRange();
733 return ExprError();
734 }
735
736 DiagnoseUseOfDecl(BoxingMethod, Loc);
737
738 ExprResult ConvertedValueExpr;
739 if (ValueType->isObjCBoxableRecordType()) {
740 InitializedEntity IE = InitializedEntity::InitializeTemporary(ValueType);
741 ConvertedValueExpr = PerformCopyInitialization(IE, ValueExpr->getExprLoc(),
742 ValueExpr);
743 } else {
744 // Convert the expression to the type that the parameter requires.
745 ParmVarDecl *ParamDecl = BoxingMethod->parameters()[0];
746 InitializedEntity IE = InitializedEntity::InitializeParameter(Context,
747 ParamDecl);
748 ConvertedValueExpr = PerformCopyInitialization(IE, SourceLocation(),
749 ValueExpr);
750 }
751
752 if (ConvertedValueExpr.isInvalid())
753 return ExprError();
754 ValueExpr = ConvertedValueExpr.get();
755
756 ObjCBoxedExpr *BoxedExpr =
757 new (Context) ObjCBoxedExpr(ValueExpr, BoxedType,
758 BoxingMethod, SR);
759 return MaybeBindToTemporary(BoxedExpr);
760 }
761
762 /// Build an ObjC subscript pseudo-object expression, given that
763 /// that's supported by the runtime.
BuildObjCSubscriptExpression(SourceLocation RB,Expr * BaseExpr,Expr * IndexExpr,ObjCMethodDecl * getterMethod,ObjCMethodDecl * setterMethod)764 ExprResult Sema::BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr,
765 Expr *IndexExpr,
766 ObjCMethodDecl *getterMethod,
767 ObjCMethodDecl *setterMethod) {
768 assert(!LangOpts.isSubscriptPointerArithmetic());
769
770 // We can't get dependent types here; our callers should have
771 // filtered them out.
772 assert((!BaseExpr->isTypeDependent() && !IndexExpr->isTypeDependent()) &&
773 "base or index cannot have dependent type here");
774
775 // Filter out placeholders in the index. In theory, overloads could
776 // be preserved here, although that might not actually work correctly.
777 ExprResult Result = CheckPlaceholderExpr(IndexExpr);
778 if (Result.isInvalid())
779 return ExprError();
780 IndexExpr = Result.get();
781
782 // Perform lvalue-to-rvalue conversion on the base.
783 Result = DefaultLvalueConversion(BaseExpr);
784 if (Result.isInvalid())
785 return ExprError();
786 BaseExpr = Result.get();
787
788 // Build the pseudo-object expression.
789 return new (Context) ObjCSubscriptRefExpr(
790 BaseExpr, IndexExpr, Context.PseudoObjectTy, VK_LValue, OK_ObjCSubscript,
791 getterMethod, setterMethod, RB);
792 }
793
BuildObjCArrayLiteral(SourceRange SR,MultiExprArg Elements)794 ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
795 SourceLocation Loc = SR.getBegin();
796
797 if (!NSArrayDecl) {
798 NSArrayDecl = LookupObjCInterfaceDeclForLiteral(*this, Loc,
799 Sema::LK_Array);
800 if (!NSArrayDecl) {
801 return ExprError();
802 }
803 }
804
805 // Find the arrayWithObjects:count: method, if we haven't done so already.
806 QualType IdT = Context.getObjCIdType();
807 if (!ArrayWithObjectsMethod) {
808 Selector
809 Sel = NSAPIObj->getNSArraySelector(NSAPI::NSArr_arrayWithObjectsCount);
810 ObjCMethodDecl *Method = NSArrayDecl->lookupClassMethod(Sel);
811 if (!Method && getLangOpts().DebuggerObjCLiteral) {
812 TypeSourceInfo *ReturnTInfo = nullptr;
813 Method = ObjCMethodDecl::Create(
814 Context, SourceLocation(), SourceLocation(), Sel, IdT, ReturnTInfo,
815 Context.getTranslationUnitDecl(), false /*Instance*/,
816 false /*isVariadic*/,
817 /*isPropertyAccessor=*/false, /*isSynthesizedAccessorStub=*/false,
818 /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
819 ObjCMethodDecl::Required, false);
820 SmallVector<ParmVarDecl *, 2> Params;
821 ParmVarDecl *objects = ParmVarDecl::Create(Context, Method,
822 SourceLocation(),
823 SourceLocation(),
824 &Context.Idents.get("objects"),
825 Context.getPointerType(IdT),
826 /*TInfo=*/nullptr,
827 SC_None, nullptr);
828 Params.push_back(objects);
829 ParmVarDecl *cnt = ParmVarDecl::Create(Context, Method,
830 SourceLocation(),
831 SourceLocation(),
832 &Context.Idents.get("cnt"),
833 Context.UnsignedLongTy,
834 /*TInfo=*/nullptr, SC_None,
835 nullptr);
836 Params.push_back(cnt);
837 Method->setMethodParams(Context, Params, std::nullopt);
838 }
839
840 if (!validateBoxingMethod(*this, Loc, NSArrayDecl, Sel, Method))
841 return ExprError();
842
843 // Dig out the type that all elements should be converted to.
844 QualType T = Method->parameters()[0]->getType();
845 const PointerType *PtrT = T->getAs<PointerType>();
846 if (!PtrT ||
847 !Context.hasSameUnqualifiedType(PtrT->getPointeeType(), IdT)) {
848 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
849 << Sel;
850 Diag(Method->parameters()[0]->getLocation(),
851 diag::note_objc_literal_method_param)
852 << 0 << T
853 << Context.getPointerType(IdT.withConst());
854 return ExprError();
855 }
856
857 // Check that the 'count' parameter is integral.
858 if (!Method->parameters()[1]->getType()->isIntegerType()) {
859 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
860 << Sel;
861 Diag(Method->parameters()[1]->getLocation(),
862 diag::note_objc_literal_method_param)
863 << 1
864 << Method->parameters()[1]->getType()
865 << "integral";
866 return ExprError();
867 }
868
869 // We've found a good +arrayWithObjects:count: method. Save it!
870 ArrayWithObjectsMethod = Method;
871 }
872
873 QualType ObjectsType = ArrayWithObjectsMethod->parameters()[0]->getType();
874 QualType RequiredType = ObjectsType->castAs<PointerType>()->getPointeeType();
875
876 // Check that each of the elements provided is valid in a collection literal,
877 // performing conversions as necessary.
878 Expr **ElementsBuffer = Elements.data();
879 for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
880 ExprResult Converted = CheckObjCCollectionLiteralElement(*this,
881 ElementsBuffer[I],
882 RequiredType, true);
883 if (Converted.isInvalid())
884 return ExprError();
885
886 ElementsBuffer[I] = Converted.get();
887 }
888
889 QualType Ty
890 = Context.getObjCObjectPointerType(
891 Context.getObjCInterfaceType(NSArrayDecl));
892
893 return MaybeBindToTemporary(
894 ObjCArrayLiteral::Create(Context, Elements, Ty,
895 ArrayWithObjectsMethod, SR));
896 }
897
898 /// Check for duplicate keys in an ObjC dictionary literal. For instance:
899 /// NSDictionary *nd = @{ @"foo" : @"bar", @"foo" : @"baz" };
900 static void
CheckObjCDictionaryLiteralDuplicateKeys(Sema & S,ObjCDictionaryLiteral * Literal)901 CheckObjCDictionaryLiteralDuplicateKeys(Sema &S,
902 ObjCDictionaryLiteral *Literal) {
903 if (Literal->isValueDependent() || Literal->isTypeDependent())
904 return;
905
906 // NSNumber has quite relaxed equality semantics (for instance, @YES is
907 // considered equal to @1.0). For now, ignore floating points and just do a
908 // bit-width and sign agnostic integer compare.
909 struct APSIntCompare {
910 bool operator()(const llvm::APSInt &LHS, const llvm::APSInt &RHS) const {
911 return llvm::APSInt::compareValues(LHS, RHS) < 0;
912 }
913 };
914
915 llvm::DenseMap<StringRef, SourceLocation> StringKeys;
916 std::map<llvm::APSInt, SourceLocation, APSIntCompare> IntegralKeys;
917
918 auto checkOneKey = [&](auto &Map, const auto &Key, SourceLocation Loc) {
919 auto Pair = Map.insert({Key, Loc});
920 if (!Pair.second) {
921 S.Diag(Loc, diag::warn_nsdictionary_duplicate_key);
922 S.Diag(Pair.first->second, diag::note_nsdictionary_duplicate_key_here);
923 }
924 };
925
926 for (unsigned Idx = 0, End = Literal->getNumElements(); Idx != End; ++Idx) {
927 Expr *Key = Literal->getKeyValueElement(Idx).Key->IgnoreParenImpCasts();
928
929 if (auto *StrLit = dyn_cast<ObjCStringLiteral>(Key)) {
930 StringRef Bytes = StrLit->getString()->getBytes();
931 SourceLocation Loc = StrLit->getExprLoc();
932 checkOneKey(StringKeys, Bytes, Loc);
933 }
934
935 if (auto *BE = dyn_cast<ObjCBoxedExpr>(Key)) {
936 Expr *Boxed = BE->getSubExpr();
937 SourceLocation Loc = BE->getExprLoc();
938
939 // Check for @("foo").
940 if (auto *Str = dyn_cast<StringLiteral>(Boxed->IgnoreParenImpCasts())) {
941 checkOneKey(StringKeys, Str->getBytes(), Loc);
942 continue;
943 }
944
945 Expr::EvalResult Result;
946 if (Boxed->EvaluateAsInt(Result, S.getASTContext(),
947 Expr::SE_AllowSideEffects)) {
948 checkOneKey(IntegralKeys, Result.Val.getInt(), Loc);
949 }
950 }
951 }
952 }
953
BuildObjCDictionaryLiteral(SourceRange SR,MutableArrayRef<ObjCDictionaryElement> Elements)954 ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR,
955 MutableArrayRef<ObjCDictionaryElement> Elements) {
956 SourceLocation Loc = SR.getBegin();
957
958 if (!NSDictionaryDecl) {
959 NSDictionaryDecl = LookupObjCInterfaceDeclForLiteral(*this, Loc,
960 Sema::LK_Dictionary);
961 if (!NSDictionaryDecl) {
962 return ExprError();
963 }
964 }
965
966 // Find the dictionaryWithObjects:forKeys:count: method, if we haven't done
967 // so already.
968 QualType IdT = Context.getObjCIdType();
969 if (!DictionaryWithObjectsMethod) {
970 Selector Sel = NSAPIObj->getNSDictionarySelector(
971 NSAPI::NSDict_dictionaryWithObjectsForKeysCount);
972 ObjCMethodDecl *Method = NSDictionaryDecl->lookupClassMethod(Sel);
973 if (!Method && getLangOpts().DebuggerObjCLiteral) {
974 Method = ObjCMethodDecl::Create(
975 Context, SourceLocation(), SourceLocation(), Sel, IdT,
976 nullptr /*TypeSourceInfo */, Context.getTranslationUnitDecl(),
977 false /*Instance*/, false /*isVariadic*/,
978 /*isPropertyAccessor=*/false,
979 /*isSynthesizedAccessorStub=*/false,
980 /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
981 ObjCMethodDecl::Required, false);
982 SmallVector<ParmVarDecl *, 3> Params;
983 ParmVarDecl *objects = ParmVarDecl::Create(Context, Method,
984 SourceLocation(),
985 SourceLocation(),
986 &Context.Idents.get("objects"),
987 Context.getPointerType(IdT),
988 /*TInfo=*/nullptr, SC_None,
989 nullptr);
990 Params.push_back(objects);
991 ParmVarDecl *keys = ParmVarDecl::Create(Context, Method,
992 SourceLocation(),
993 SourceLocation(),
994 &Context.Idents.get("keys"),
995 Context.getPointerType(IdT),
996 /*TInfo=*/nullptr, SC_None,
997 nullptr);
998 Params.push_back(keys);
999 ParmVarDecl *cnt = ParmVarDecl::Create(Context, Method,
1000 SourceLocation(),
1001 SourceLocation(),
1002 &Context.Idents.get("cnt"),
1003 Context.UnsignedLongTy,
1004 /*TInfo=*/nullptr, SC_None,
1005 nullptr);
1006 Params.push_back(cnt);
1007 Method->setMethodParams(Context, Params, std::nullopt);
1008 }
1009
1010 if (!validateBoxingMethod(*this, SR.getBegin(), NSDictionaryDecl, Sel,
1011 Method))
1012 return ExprError();
1013
1014 // Dig out the type that all values should be converted to.
1015 QualType ValueT = Method->parameters()[0]->getType();
1016 const PointerType *PtrValue = ValueT->getAs<PointerType>();
1017 if (!PtrValue ||
1018 !Context.hasSameUnqualifiedType(PtrValue->getPointeeType(), IdT)) {
1019 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1020 << Sel;
1021 Diag(Method->parameters()[0]->getLocation(),
1022 diag::note_objc_literal_method_param)
1023 << 0 << ValueT
1024 << Context.getPointerType(IdT.withConst());
1025 return ExprError();
1026 }
1027
1028 // Dig out the type that all keys should be converted to.
1029 QualType KeyT = Method->parameters()[1]->getType();
1030 const PointerType *PtrKey = KeyT->getAs<PointerType>();
1031 if (!PtrKey ||
1032 !Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),
1033 IdT)) {
1034 bool err = true;
1035 if (PtrKey) {
1036 if (QIDNSCopying.isNull()) {
1037 // key argument of selector is id<NSCopying>?
1038 if (ObjCProtocolDecl *NSCopyingPDecl =
1039 LookupProtocol(&Context.Idents.get("NSCopying"), SR.getBegin())) {
1040 ObjCProtocolDecl *PQ[] = {NSCopyingPDecl};
1041 QIDNSCopying = Context.getObjCObjectType(
1042 Context.ObjCBuiltinIdTy, {},
1043 llvm::ArrayRef((ObjCProtocolDecl **)PQ, 1), false);
1044 QIDNSCopying = Context.getObjCObjectPointerType(QIDNSCopying);
1045 }
1046 }
1047 if (!QIDNSCopying.isNull())
1048 err = !Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),
1049 QIDNSCopying);
1050 }
1051
1052 if (err) {
1053 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1054 << Sel;
1055 Diag(Method->parameters()[1]->getLocation(),
1056 diag::note_objc_literal_method_param)
1057 << 1 << KeyT
1058 << Context.getPointerType(IdT.withConst());
1059 return ExprError();
1060 }
1061 }
1062
1063 // Check that the 'count' parameter is integral.
1064 QualType CountType = Method->parameters()[2]->getType();
1065 if (!CountType->isIntegerType()) {
1066 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1067 << Sel;
1068 Diag(Method->parameters()[2]->getLocation(),
1069 diag::note_objc_literal_method_param)
1070 << 2 << CountType
1071 << "integral";
1072 return ExprError();
1073 }
1074
1075 // We've found a good +dictionaryWithObjects:keys:count: method; save it!
1076 DictionaryWithObjectsMethod = Method;
1077 }
1078
1079 QualType ValuesT = DictionaryWithObjectsMethod->parameters()[0]->getType();
1080 QualType ValueT = ValuesT->castAs<PointerType>()->getPointeeType();
1081 QualType KeysT = DictionaryWithObjectsMethod->parameters()[1]->getType();
1082 QualType KeyT = KeysT->castAs<PointerType>()->getPointeeType();
1083
1084 // Check that each of the keys and values provided is valid in a collection
1085 // literal, performing conversions as necessary.
1086 bool HasPackExpansions = false;
1087 for (ObjCDictionaryElement &Element : Elements) {
1088 // Check the key.
1089 ExprResult Key = CheckObjCCollectionLiteralElement(*this, Element.Key,
1090 KeyT);
1091 if (Key.isInvalid())
1092 return ExprError();
1093
1094 // Check the value.
1095 ExprResult Value
1096 = CheckObjCCollectionLiteralElement(*this, Element.Value, ValueT);
1097 if (Value.isInvalid())
1098 return ExprError();
1099
1100 Element.Key = Key.get();
1101 Element.Value = Value.get();
1102
1103 if (Element.EllipsisLoc.isInvalid())
1104 continue;
1105
1106 if (!Element.Key->containsUnexpandedParameterPack() &&
1107 !Element.Value->containsUnexpandedParameterPack()) {
1108 Diag(Element.EllipsisLoc,
1109 diag::err_pack_expansion_without_parameter_packs)
1110 << SourceRange(Element.Key->getBeginLoc(),
1111 Element.Value->getEndLoc());
1112 return ExprError();
1113 }
1114
1115 HasPackExpansions = true;
1116 }
1117
1118 QualType Ty = Context.getObjCObjectPointerType(
1119 Context.getObjCInterfaceType(NSDictionaryDecl));
1120
1121 auto *Literal =
1122 ObjCDictionaryLiteral::Create(Context, Elements, HasPackExpansions, Ty,
1123 DictionaryWithObjectsMethod, SR);
1124 CheckObjCDictionaryLiteralDuplicateKeys(*this, Literal);
1125 return MaybeBindToTemporary(Literal);
1126 }
1127
BuildObjCEncodeExpression(SourceLocation AtLoc,TypeSourceInfo * EncodedTypeInfo,SourceLocation RParenLoc)1128 ExprResult Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
1129 TypeSourceInfo *EncodedTypeInfo,
1130 SourceLocation RParenLoc) {
1131 QualType EncodedType = EncodedTypeInfo->getType();
1132 QualType StrTy;
1133 if (EncodedType->isDependentType())
1134 StrTy = Context.DependentTy;
1135 else {
1136 if (!EncodedType->getAsArrayTypeUnsafe() && //// Incomplete array is handled.
1137 !EncodedType->isVoidType()) // void is handled too.
1138 if (RequireCompleteType(AtLoc, EncodedType,
1139 diag::err_incomplete_type_objc_at_encode,
1140 EncodedTypeInfo->getTypeLoc()))
1141 return ExprError();
1142
1143 std::string Str;
1144 QualType NotEncodedT;
1145 Context.getObjCEncodingForType(EncodedType, Str, nullptr, &NotEncodedT);
1146 if (!NotEncodedT.isNull())
1147 Diag(AtLoc, diag::warn_incomplete_encoded_type)
1148 << EncodedType << NotEncodedT;
1149
1150 // The type of @encode is the same as the type of the corresponding string,
1151 // which is an array type.
1152 StrTy = Context.getStringLiteralArrayType(Context.CharTy, Str.size());
1153 }
1154
1155 return new (Context) ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc);
1156 }
1157
ParseObjCEncodeExpression(SourceLocation AtLoc,SourceLocation EncodeLoc,SourceLocation LParenLoc,ParsedType ty,SourceLocation RParenLoc)1158 ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
1159 SourceLocation EncodeLoc,
1160 SourceLocation LParenLoc,
1161 ParsedType ty,
1162 SourceLocation RParenLoc) {
1163 // FIXME: Preserve type source info ?
1164 TypeSourceInfo *TInfo;
1165 QualType EncodedType = GetTypeFromParser(ty, &TInfo);
1166 if (!TInfo)
1167 TInfo = Context.getTrivialTypeSourceInfo(EncodedType,
1168 getLocForEndOfToken(LParenLoc));
1169
1170 return BuildObjCEncodeExpression(AtLoc, TInfo, RParenLoc);
1171 }
1172
HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema & S,SourceLocation AtLoc,SourceLocation LParenLoc,SourceLocation RParenLoc,ObjCMethodDecl * Method,ObjCMethodList & MethList)1173 static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S,
1174 SourceLocation AtLoc,
1175 SourceLocation LParenLoc,
1176 SourceLocation RParenLoc,
1177 ObjCMethodDecl *Method,
1178 ObjCMethodList &MethList) {
1179 ObjCMethodList *M = &MethList;
1180 bool Warned = false;
1181 for (M = M->getNext(); M; M=M->getNext()) {
1182 ObjCMethodDecl *MatchingMethodDecl = M->getMethod();
1183 if (MatchingMethodDecl == Method ||
1184 isa<ObjCImplDecl>(MatchingMethodDecl->getDeclContext()) ||
1185 MatchingMethodDecl->getSelector() != Method->getSelector())
1186 continue;
1187 if (!S.MatchTwoMethodDeclarations(Method,
1188 MatchingMethodDecl, Sema::MMS_loose)) {
1189 if (!Warned) {
1190 Warned = true;
1191 S.Diag(AtLoc, diag::warn_multiple_selectors)
1192 << Method->getSelector() << FixItHint::CreateInsertion(LParenLoc, "(")
1193 << FixItHint::CreateInsertion(RParenLoc, ")");
1194 S.Diag(Method->getLocation(), diag::note_method_declared_at)
1195 << Method->getDeclName();
1196 }
1197 S.Diag(MatchingMethodDecl->getLocation(), diag::note_method_declared_at)
1198 << MatchingMethodDecl->getDeclName();
1199 }
1200 }
1201 return Warned;
1202 }
1203
DiagnoseMismatchedSelectors(Sema & S,SourceLocation AtLoc,ObjCMethodDecl * Method,SourceLocation LParenLoc,SourceLocation RParenLoc,bool WarnMultipleSelectors)1204 static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc,
1205 ObjCMethodDecl *Method,
1206 SourceLocation LParenLoc,
1207 SourceLocation RParenLoc,
1208 bool WarnMultipleSelectors) {
1209 if (!WarnMultipleSelectors ||
1210 S.Diags.isIgnored(diag::warn_multiple_selectors, SourceLocation()))
1211 return;
1212 bool Warned = false;
1213 for (Sema::GlobalMethodPool::iterator b = S.MethodPool.begin(),
1214 e = S.MethodPool.end(); b != e; b++) {
1215 // first, instance methods
1216 ObjCMethodList &InstMethList = b->second.first;
1217 if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,
1218 Method, InstMethList))
1219 Warned = true;
1220
1221 // second, class methods
1222 ObjCMethodList &ClsMethList = b->second.second;
1223 if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,
1224 Method, ClsMethList) || Warned)
1225 return;
1226 }
1227 }
1228
LookupDirectMethodInMethodList(Sema & S,Selector Sel,ObjCMethodList & MethList,bool & onlyDirect,bool & anyDirect)1229 static ObjCMethodDecl *LookupDirectMethodInMethodList(Sema &S, Selector Sel,
1230 ObjCMethodList &MethList,
1231 bool &onlyDirect,
1232 bool &anyDirect) {
1233 (void)Sel;
1234 ObjCMethodList *M = &MethList;
1235 ObjCMethodDecl *DirectMethod = nullptr;
1236 for (; M; M = M->getNext()) {
1237 ObjCMethodDecl *Method = M->getMethod();
1238 if (!Method)
1239 continue;
1240 assert(Method->getSelector() == Sel && "Method with wrong selector in method list");
1241 if (Method->isDirectMethod()) {
1242 anyDirect = true;
1243 DirectMethod = Method;
1244 } else
1245 onlyDirect = false;
1246 }
1247
1248 return DirectMethod;
1249 }
1250
1251 // Search the global pool for (potentially) direct methods matching the given
1252 // selector. If a non-direct method is found, set \param onlyDirect to false. If
1253 // a direct method is found, set \param anyDirect to true. Returns a direct
1254 // method, if any.
LookupDirectMethodInGlobalPool(Sema & S,Selector Sel,bool & onlyDirect,bool & anyDirect)1255 static ObjCMethodDecl *LookupDirectMethodInGlobalPool(Sema &S, Selector Sel,
1256 bool &onlyDirect,
1257 bool &anyDirect) {
1258 auto Iter = S.MethodPool.find(Sel);
1259 if (Iter == S.MethodPool.end())
1260 return nullptr;
1261
1262 ObjCMethodDecl *DirectInstance = LookupDirectMethodInMethodList(
1263 S, Sel, Iter->second.first, onlyDirect, anyDirect);
1264 ObjCMethodDecl *DirectClass = LookupDirectMethodInMethodList(
1265 S, Sel, Iter->second.second, onlyDirect, anyDirect);
1266
1267 return DirectInstance ? DirectInstance : DirectClass;
1268 }
1269
findMethodInCurrentClass(Sema & S,Selector Sel)1270 static ObjCMethodDecl *findMethodInCurrentClass(Sema &S, Selector Sel) {
1271 auto *CurMD = S.getCurMethodDecl();
1272 if (!CurMD)
1273 return nullptr;
1274 ObjCInterfaceDecl *IFace = CurMD->getClassInterface();
1275
1276 // The language enforce that only one direct method is present in a given
1277 // class, so we just need to find one method in the current class to know
1278 // whether Sel is potentially direct in this context.
1279 if (ObjCMethodDecl *MD = IFace->lookupMethod(Sel, /*isInstance=*/true))
1280 return MD;
1281 if (ObjCMethodDecl *MD = IFace->lookupPrivateMethod(Sel, /*Instance=*/true))
1282 return MD;
1283 if (ObjCMethodDecl *MD = IFace->lookupMethod(Sel, /*isInstance=*/false))
1284 return MD;
1285 if (ObjCMethodDecl *MD = IFace->lookupPrivateMethod(Sel, /*Instance=*/false))
1286 return MD;
1287
1288 return nullptr;
1289 }
1290
ParseObjCSelectorExpression(Selector Sel,SourceLocation AtLoc,SourceLocation SelLoc,SourceLocation LParenLoc,SourceLocation RParenLoc,bool WarnMultipleSelectors)1291 ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
1292 SourceLocation AtLoc,
1293 SourceLocation SelLoc,
1294 SourceLocation LParenLoc,
1295 SourceLocation RParenLoc,
1296 bool WarnMultipleSelectors) {
1297 ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,
1298 SourceRange(LParenLoc, RParenLoc));
1299 if (!Method)
1300 Method = LookupFactoryMethodInGlobalPool(Sel,
1301 SourceRange(LParenLoc, RParenLoc));
1302 if (!Method) {
1303 if (const ObjCMethodDecl *OM = SelectorsForTypoCorrection(Sel)) {
1304 Selector MatchedSel = OM->getSelector();
1305 SourceRange SelectorRange(LParenLoc.getLocWithOffset(1),
1306 RParenLoc.getLocWithOffset(-1));
1307 Diag(SelLoc, diag::warn_undeclared_selector_with_typo)
1308 << Sel << MatchedSel
1309 << FixItHint::CreateReplacement(SelectorRange, MatchedSel.getAsString());
1310
1311 } else
1312 Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
1313 } else {
1314 DiagnoseMismatchedSelectors(*this, AtLoc, Method, LParenLoc, RParenLoc,
1315 WarnMultipleSelectors);
1316
1317 bool onlyDirect = true;
1318 bool anyDirect = false;
1319 ObjCMethodDecl *GlobalDirectMethod =
1320 LookupDirectMethodInGlobalPool(*this, Sel, onlyDirect, anyDirect);
1321
1322 if (onlyDirect) {
1323 Diag(AtLoc, diag::err_direct_selector_expression)
1324 << Method->getSelector();
1325 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
1326 << Method->getDeclName();
1327 } else if (anyDirect) {
1328 // If we saw any direct methods, see if we see a direct member of the
1329 // current class. If so, the @selector will likely be used to refer to
1330 // this direct method.
1331 ObjCMethodDecl *LikelyTargetMethod = findMethodInCurrentClass(*this, Sel);
1332 if (LikelyTargetMethod && LikelyTargetMethod->isDirectMethod()) {
1333 Diag(AtLoc, diag::warn_potentially_direct_selector_expression) << Sel;
1334 Diag(LikelyTargetMethod->getLocation(),
1335 diag::note_direct_method_declared_at)
1336 << LikelyTargetMethod->getDeclName();
1337 } else if (!LikelyTargetMethod) {
1338 // Otherwise, emit the "strict" variant of this diagnostic, unless
1339 // LikelyTargetMethod is non-direct.
1340 Diag(AtLoc, diag::warn_strict_potentially_direct_selector_expression)
1341 << Sel;
1342 Diag(GlobalDirectMethod->getLocation(),
1343 diag::note_direct_method_declared_at)
1344 << GlobalDirectMethod->getDeclName();
1345 }
1346 }
1347 }
1348
1349 if (Method &&
1350 Method->getImplementationControl() != ObjCMethodDecl::Optional &&
1351 !getSourceManager().isInSystemHeader(Method->getLocation()))
1352 ReferencedSelectors.insert(std::make_pair(Sel, AtLoc));
1353
1354 // In ARC, forbid the user from using @selector for
1355 // retain/release/autorelease/dealloc/retainCount.
1356 if (getLangOpts().ObjCAutoRefCount) {
1357 switch (Sel.getMethodFamily()) {
1358 case OMF_retain:
1359 case OMF_release:
1360 case OMF_autorelease:
1361 case OMF_retainCount:
1362 case OMF_dealloc:
1363 Diag(AtLoc, diag::err_arc_illegal_selector) <<
1364 Sel << SourceRange(LParenLoc, RParenLoc);
1365 break;
1366
1367 case OMF_None:
1368 case OMF_alloc:
1369 case OMF_copy:
1370 case OMF_finalize:
1371 case OMF_init:
1372 case OMF_mutableCopy:
1373 case OMF_new:
1374 case OMF_self:
1375 case OMF_initialize:
1376 case OMF_performSelector:
1377 break;
1378 }
1379 }
1380 QualType Ty = Context.getObjCSelType();
1381 return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);
1382 }
1383
ParseObjCProtocolExpression(IdentifierInfo * ProtocolId,SourceLocation AtLoc,SourceLocation ProtoLoc,SourceLocation LParenLoc,SourceLocation ProtoIdLoc,SourceLocation RParenLoc)1384 ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
1385 SourceLocation AtLoc,
1386 SourceLocation ProtoLoc,
1387 SourceLocation LParenLoc,
1388 SourceLocation ProtoIdLoc,
1389 SourceLocation RParenLoc) {
1390 ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId, ProtoIdLoc);
1391 if (!PDecl) {
1392 Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
1393 return true;
1394 }
1395 if (PDecl->isNonRuntimeProtocol())
1396 Diag(ProtoLoc, diag::err_objc_non_runtime_protocol_in_protocol_expr)
1397 << PDecl;
1398 if (!PDecl->hasDefinition()) {
1399 Diag(ProtoLoc, diag::err_atprotocol_protocol) << PDecl;
1400 Diag(PDecl->getLocation(), diag::note_entity_declared_at) << PDecl;
1401 } else {
1402 PDecl = PDecl->getDefinition();
1403 }
1404
1405 QualType Ty = Context.getObjCProtoType();
1406 if (Ty.isNull())
1407 return true;
1408 Ty = Context.getObjCObjectPointerType(Ty);
1409 return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, ProtoIdLoc, RParenLoc);
1410 }
1411
1412 /// Try to capture an implicit reference to 'self'.
tryCaptureObjCSelf(SourceLocation Loc)1413 ObjCMethodDecl *Sema::tryCaptureObjCSelf(SourceLocation Loc) {
1414 DeclContext *DC = getFunctionLevelDeclContext();
1415
1416 // If we're not in an ObjC method, error out. Note that, unlike the
1417 // C++ case, we don't require an instance method --- class methods
1418 // still have a 'self', and we really do still need to capture it!
1419 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(DC);
1420 if (!method)
1421 return nullptr;
1422
1423 tryCaptureVariable(method->getSelfDecl(), Loc);
1424
1425 return method;
1426 }
1427
stripObjCInstanceType(ASTContext & Context,QualType T)1428 static QualType stripObjCInstanceType(ASTContext &Context, QualType T) {
1429 QualType origType = T;
1430 if (auto nullability = AttributedType::stripOuterNullability(T)) {
1431 if (T == Context.getObjCInstanceType()) {
1432 return Context.getAttributedType(
1433 AttributedType::getNullabilityAttrKind(*nullability),
1434 Context.getObjCIdType(),
1435 Context.getObjCIdType());
1436 }
1437
1438 return origType;
1439 }
1440
1441 if (T == Context.getObjCInstanceType())
1442 return Context.getObjCIdType();
1443
1444 return origType;
1445 }
1446
1447 /// Determine the result type of a message send based on the receiver type,
1448 /// method, and the kind of message send.
1449 ///
1450 /// This is the "base" result type, which will still need to be adjusted
1451 /// to account for nullability.
getBaseMessageSendResultType(Sema & S,QualType ReceiverType,ObjCMethodDecl * Method,bool isClassMessage,bool isSuperMessage)1452 static QualType getBaseMessageSendResultType(Sema &S,
1453 QualType ReceiverType,
1454 ObjCMethodDecl *Method,
1455 bool isClassMessage,
1456 bool isSuperMessage) {
1457 assert(Method && "Must have a method");
1458 if (!Method->hasRelatedResultType())
1459 return Method->getSendResultType(ReceiverType);
1460
1461 ASTContext &Context = S.Context;
1462
1463 // Local function that transfers the nullability of the method's
1464 // result type to the returned result.
1465 auto transferNullability = [&](QualType type) -> QualType {
1466 // If the method's result type has nullability, extract it.
1467 if (auto nullability =
1468 Method->getSendResultType(ReceiverType)->getNullability()) {
1469 // Strip off any outer nullability sugar from the provided type.
1470 (void)AttributedType::stripOuterNullability(type);
1471
1472 // Form a new attributed type using the method result type's nullability.
1473 return Context.getAttributedType(
1474 AttributedType::getNullabilityAttrKind(*nullability),
1475 type,
1476 type);
1477 }
1478
1479 return type;
1480 };
1481
1482 // If a method has a related return type:
1483 // - if the method found is an instance method, but the message send
1484 // was a class message send, T is the declared return type of the method
1485 // found
1486 if (Method->isInstanceMethod() && isClassMessage)
1487 return stripObjCInstanceType(Context,
1488 Method->getSendResultType(ReceiverType));
1489
1490 // - if the receiver is super, T is a pointer to the class of the
1491 // enclosing method definition
1492 if (isSuperMessage) {
1493 if (ObjCMethodDecl *CurMethod = S.getCurMethodDecl())
1494 if (ObjCInterfaceDecl *Class = CurMethod->getClassInterface()) {
1495 return transferNullability(
1496 Context.getObjCObjectPointerType(
1497 Context.getObjCInterfaceType(Class)));
1498 }
1499 }
1500
1501 // - if the receiver is the name of a class U, T is a pointer to U
1502 if (ReceiverType->getAsObjCInterfaceType())
1503 return transferNullability(Context.getObjCObjectPointerType(ReceiverType));
1504 // - if the receiver is of type Class or qualified Class type,
1505 // T is the declared return type of the method.
1506 if (ReceiverType->isObjCClassType() ||
1507 ReceiverType->isObjCQualifiedClassType())
1508 return stripObjCInstanceType(Context,
1509 Method->getSendResultType(ReceiverType));
1510
1511 // - if the receiver is id, qualified id, Class, or qualified Class, T
1512 // is the receiver type, otherwise
1513 // - T is the type of the receiver expression.
1514 return transferNullability(ReceiverType);
1515 }
1516
getMessageSendResultType(const Expr * Receiver,QualType ReceiverType,ObjCMethodDecl * Method,bool isClassMessage,bool isSuperMessage)1517 QualType Sema::getMessageSendResultType(const Expr *Receiver,
1518 QualType ReceiverType,
1519 ObjCMethodDecl *Method,
1520 bool isClassMessage,
1521 bool isSuperMessage) {
1522 // Produce the result type.
1523 QualType resultType = getBaseMessageSendResultType(*this, ReceiverType,
1524 Method,
1525 isClassMessage,
1526 isSuperMessage);
1527
1528 // If this is a class message, ignore the nullability of the receiver.
1529 if (isClassMessage) {
1530 // In a class method, class messages to 'self' that return instancetype can
1531 // be typed as the current class. We can safely do this in ARC because self
1532 // can't be reassigned, and we do it unsafely outside of ARC because in
1533 // practice people never reassign self in class methods and there's some
1534 // virtue in not being aggressively pedantic.
1535 if (Receiver && Receiver->isObjCSelfExpr()) {
1536 assert(ReceiverType->isObjCClassType() && "expected a Class self");
1537 QualType T = Method->getSendResultType(ReceiverType);
1538 AttributedType::stripOuterNullability(T);
1539 if (T == Context.getObjCInstanceType()) {
1540 const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(
1541 cast<ImplicitParamDecl>(
1542 cast<DeclRefExpr>(Receiver->IgnoreParenImpCasts())->getDecl())
1543 ->getDeclContext());
1544 assert(MD->isClassMethod() && "expected a class method");
1545 QualType NewResultType = Context.getObjCObjectPointerType(
1546 Context.getObjCInterfaceType(MD->getClassInterface()));
1547 if (auto Nullability = resultType->getNullability())
1548 NewResultType = Context.getAttributedType(
1549 AttributedType::getNullabilityAttrKind(*Nullability),
1550 NewResultType, NewResultType);
1551 return NewResultType;
1552 }
1553 }
1554 return resultType;
1555 }
1556
1557 // There is nothing left to do if the result type cannot have a nullability
1558 // specifier.
1559 if (!resultType->canHaveNullability())
1560 return resultType;
1561
1562 // Map the nullability of the result into a table index.
1563 unsigned receiverNullabilityIdx = 0;
1564 if (std::optional<NullabilityKind> nullability =
1565 ReceiverType->getNullability()) {
1566 if (*nullability == NullabilityKind::NullableResult)
1567 nullability = NullabilityKind::Nullable;
1568 receiverNullabilityIdx = 1 + static_cast<unsigned>(*nullability);
1569 }
1570
1571 unsigned resultNullabilityIdx = 0;
1572 if (std::optional<NullabilityKind> nullability =
1573 resultType->getNullability()) {
1574 if (*nullability == NullabilityKind::NullableResult)
1575 nullability = NullabilityKind::Nullable;
1576 resultNullabilityIdx = 1 + static_cast<unsigned>(*nullability);
1577 }
1578
1579 // The table of nullability mappings, indexed by the receiver's nullability
1580 // and then the result type's nullability.
1581 static const uint8_t None = 0;
1582 static const uint8_t NonNull = 1;
1583 static const uint8_t Nullable = 2;
1584 static const uint8_t Unspecified = 3;
1585 static const uint8_t nullabilityMap[4][4] = {
1586 // None NonNull Nullable Unspecified
1587 /* None */ { None, None, Nullable, None },
1588 /* NonNull */ { None, NonNull, Nullable, Unspecified },
1589 /* Nullable */ { Nullable, Nullable, Nullable, Nullable },
1590 /* Unspecified */ { None, Unspecified, Nullable, Unspecified }
1591 };
1592
1593 unsigned newResultNullabilityIdx
1594 = nullabilityMap[receiverNullabilityIdx][resultNullabilityIdx];
1595 if (newResultNullabilityIdx == resultNullabilityIdx)
1596 return resultType;
1597
1598 // Strip off the existing nullability. This removes as little type sugar as
1599 // possible.
1600 do {
1601 if (auto attributed = dyn_cast<AttributedType>(resultType.getTypePtr())) {
1602 resultType = attributed->getModifiedType();
1603 } else {
1604 resultType = resultType.getDesugaredType(Context);
1605 }
1606 } while (resultType->getNullability());
1607
1608 // Add nullability back if needed.
1609 if (newResultNullabilityIdx > 0) {
1610 auto newNullability
1611 = static_cast<NullabilityKind>(newResultNullabilityIdx-1);
1612 return Context.getAttributedType(
1613 AttributedType::getNullabilityAttrKind(newNullability),
1614 resultType, resultType);
1615 }
1616
1617 return resultType;
1618 }
1619
1620 /// Look for an ObjC method whose result type exactly matches the given type.
1621 static const ObjCMethodDecl *
findExplicitInstancetypeDeclarer(const ObjCMethodDecl * MD,QualType instancetype)1622 findExplicitInstancetypeDeclarer(const ObjCMethodDecl *MD,
1623 QualType instancetype) {
1624 if (MD->getReturnType() == instancetype)
1625 return MD;
1626
1627 // For these purposes, a method in an @implementation overrides a
1628 // declaration in the @interface.
1629 if (const ObjCImplDecl *impl =
1630 dyn_cast<ObjCImplDecl>(MD->getDeclContext())) {
1631 const ObjCContainerDecl *iface;
1632 if (const ObjCCategoryImplDecl *catImpl =
1633 dyn_cast<ObjCCategoryImplDecl>(impl)) {
1634 iface = catImpl->getCategoryDecl();
1635 } else {
1636 iface = impl->getClassInterface();
1637 }
1638
1639 const ObjCMethodDecl *ifaceMD =
1640 iface->getMethod(MD->getSelector(), MD->isInstanceMethod());
1641 if (ifaceMD) return findExplicitInstancetypeDeclarer(ifaceMD, instancetype);
1642 }
1643
1644 SmallVector<const ObjCMethodDecl *, 4> overrides;
1645 MD->getOverriddenMethods(overrides);
1646 for (unsigned i = 0, e = overrides.size(); i != e; ++i) {
1647 if (const ObjCMethodDecl *result =
1648 findExplicitInstancetypeDeclarer(overrides[i], instancetype))
1649 return result;
1650 }
1651
1652 return nullptr;
1653 }
1654
EmitRelatedResultTypeNoteForReturn(QualType destType)1655 void Sema::EmitRelatedResultTypeNoteForReturn(QualType destType) {
1656 // Only complain if we're in an ObjC method and the required return
1657 // type doesn't match the method's declared return type.
1658 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CurContext);
1659 if (!MD || !MD->hasRelatedResultType() ||
1660 Context.hasSameUnqualifiedType(destType, MD->getReturnType()))
1661 return;
1662
1663 // Look for a method overridden by this method which explicitly uses
1664 // 'instancetype'.
1665 if (const ObjCMethodDecl *overridden =
1666 findExplicitInstancetypeDeclarer(MD, Context.getObjCInstanceType())) {
1667 SourceRange range = overridden->getReturnTypeSourceRange();
1668 SourceLocation loc = range.getBegin();
1669 if (loc.isInvalid())
1670 loc = overridden->getLocation();
1671 Diag(loc, diag::note_related_result_type_explicit)
1672 << /*current method*/ 1 << range;
1673 return;
1674 }
1675
1676 // Otherwise, if we have an interesting method family, note that.
1677 // This should always trigger if the above didn't.
1678 if (ObjCMethodFamily family = MD->getMethodFamily())
1679 Diag(MD->getLocation(), diag::note_related_result_type_family)
1680 << /*current method*/ 1
1681 << family;
1682 }
1683
EmitRelatedResultTypeNote(const Expr * E)1684 void Sema::EmitRelatedResultTypeNote(const Expr *E) {
1685 E = E->IgnoreParenImpCasts();
1686 const ObjCMessageExpr *MsgSend = dyn_cast<ObjCMessageExpr>(E);
1687 if (!MsgSend)
1688 return;
1689
1690 const ObjCMethodDecl *Method = MsgSend->getMethodDecl();
1691 if (!Method)
1692 return;
1693
1694 if (!Method->hasRelatedResultType())
1695 return;
1696
1697 if (Context.hasSameUnqualifiedType(
1698 Method->getReturnType().getNonReferenceType(), MsgSend->getType()))
1699 return;
1700
1701 if (!Context.hasSameUnqualifiedType(Method->getReturnType(),
1702 Context.getObjCInstanceType()))
1703 return;
1704
1705 Diag(Method->getLocation(), diag::note_related_result_type_inferred)
1706 << Method->isInstanceMethod() << Method->getSelector()
1707 << MsgSend->getType();
1708 }
1709
CheckMessageArgumentTypes(const Expr * Receiver,QualType ReceiverType,MultiExprArg Args,Selector Sel,ArrayRef<SourceLocation> SelectorLocs,ObjCMethodDecl * Method,bool isClassMessage,bool isSuperMessage,SourceLocation lbrac,SourceLocation rbrac,SourceRange RecRange,QualType & ReturnType,ExprValueKind & VK)1710 bool Sema::CheckMessageArgumentTypes(
1711 const Expr *Receiver, QualType ReceiverType, MultiExprArg Args,
1712 Selector Sel, ArrayRef<SourceLocation> SelectorLocs, ObjCMethodDecl *Method,
1713 bool isClassMessage, bool isSuperMessage, SourceLocation lbrac,
1714 SourceLocation rbrac, SourceRange RecRange, QualType &ReturnType,
1715 ExprValueKind &VK) {
1716 SourceLocation SelLoc;
1717 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
1718 SelLoc = SelectorLocs.front();
1719 else
1720 SelLoc = lbrac;
1721
1722 if (!Method) {
1723 // Apply default argument promotion as for (C99 6.5.2.2p6).
1724 for (unsigned i = 0, e = Args.size(); i != e; i++) {
1725 if (Args[i]->isTypeDependent())
1726 continue;
1727
1728 ExprResult result;
1729 if (getLangOpts().DebuggerSupport) {
1730 QualType paramTy; // ignored
1731 result = checkUnknownAnyArg(SelLoc, Args[i], paramTy);
1732 } else {
1733 result = DefaultArgumentPromotion(Args[i]);
1734 }
1735 if (result.isInvalid())
1736 return true;
1737 Args[i] = result.get();
1738 }
1739
1740 unsigned DiagID;
1741 if (getLangOpts().ObjCAutoRefCount)
1742 DiagID = diag::err_arc_method_not_found;
1743 else
1744 DiagID = isClassMessage ? diag::warn_class_method_not_found
1745 : diag::warn_inst_method_not_found;
1746 if (!getLangOpts().DebuggerSupport) {
1747 const ObjCMethodDecl *OMD = SelectorsForTypoCorrection(Sel, ReceiverType);
1748 if (OMD && !OMD->isInvalidDecl()) {
1749 if (getLangOpts().ObjCAutoRefCount)
1750 DiagID = diag::err_method_not_found_with_typo;
1751 else
1752 DiagID = isClassMessage ? diag::warn_class_method_not_found_with_typo
1753 : diag::warn_instance_method_not_found_with_typo;
1754 Selector MatchedSel = OMD->getSelector();
1755 SourceRange SelectorRange(SelectorLocs.front(), SelectorLocs.back());
1756 if (MatchedSel.isUnarySelector())
1757 Diag(SelLoc, DiagID)
1758 << Sel<< isClassMessage << MatchedSel
1759 << FixItHint::CreateReplacement(SelectorRange, MatchedSel.getAsString());
1760 else
1761 Diag(SelLoc, DiagID) << Sel<< isClassMessage << MatchedSel;
1762 }
1763 else
1764 Diag(SelLoc, DiagID)
1765 << Sel << isClassMessage << SourceRange(SelectorLocs.front(),
1766 SelectorLocs.back());
1767 // Find the class to which we are sending this message.
1768 if (auto *ObjPT = ReceiverType->getAs<ObjCObjectPointerType>()) {
1769 if (ObjCInterfaceDecl *ThisClass = ObjPT->getInterfaceDecl()) {
1770 Diag(ThisClass->getLocation(), diag::note_receiver_class_declared);
1771 if (!RecRange.isInvalid())
1772 if (ThisClass->lookupClassMethod(Sel))
1773 Diag(RecRange.getBegin(), diag::note_receiver_expr_here)
1774 << FixItHint::CreateReplacement(RecRange,
1775 ThisClass->getNameAsString());
1776 }
1777 }
1778 }
1779
1780 // In debuggers, we want to use __unknown_anytype for these
1781 // results so that clients can cast them.
1782 if (getLangOpts().DebuggerSupport) {
1783 ReturnType = Context.UnknownAnyTy;
1784 } else {
1785 ReturnType = Context.getObjCIdType();
1786 }
1787 VK = VK_PRValue;
1788 return false;
1789 }
1790
1791 ReturnType = getMessageSendResultType(Receiver, ReceiverType, Method,
1792 isClassMessage, isSuperMessage);
1793 VK = Expr::getValueKindForType(Method->getReturnType());
1794
1795 unsigned NumNamedArgs = Sel.getNumArgs();
1796 // Method might have more arguments than selector indicates. This is due
1797 // to addition of c-style arguments in method.
1798 if (Method->param_size() > Sel.getNumArgs())
1799 NumNamedArgs = Method->param_size();
1800 // FIXME. This need be cleaned up.
1801 if (Args.size() < NumNamedArgs) {
1802 Diag(SelLoc, diag::err_typecheck_call_too_few_args)
1803 << 2 << NumNamedArgs << static_cast<unsigned>(Args.size());
1804 return false;
1805 }
1806
1807 // Compute the set of type arguments to be substituted into each parameter
1808 // type.
1809 std::optional<ArrayRef<QualType>> typeArgs =
1810 ReceiverType->getObjCSubstitutions(Method->getDeclContext());
1811 bool IsError = false;
1812 for (unsigned i = 0; i < NumNamedArgs; i++) {
1813 // We can't do any type-checking on a type-dependent argument.
1814 if (Args[i]->isTypeDependent())
1815 continue;
1816
1817 Expr *argExpr = Args[i];
1818
1819 ParmVarDecl *param = Method->parameters()[i];
1820 assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
1821
1822 if (param->hasAttr<NoEscapeAttr>() &&
1823 param->getType()->isBlockPointerType())
1824 if (auto *BE = dyn_cast<BlockExpr>(
1825 argExpr->IgnoreParenNoopCasts(Context)))
1826 BE->getBlockDecl()->setDoesNotEscape();
1827
1828 // Strip the unbridged-cast placeholder expression off unless it's
1829 // a consumed argument.
1830 if (argExpr->hasPlaceholderType(BuiltinType::ARCUnbridgedCast) &&
1831 !param->hasAttr<CFConsumedAttr>())
1832 argExpr = stripARCUnbridgedCast(argExpr);
1833
1834 // If the parameter is __unknown_anytype, infer its type
1835 // from the argument.
1836 if (param->getType() == Context.UnknownAnyTy) {
1837 QualType paramType;
1838 ExprResult argE = checkUnknownAnyArg(SelLoc, argExpr, paramType);
1839 if (argE.isInvalid()) {
1840 IsError = true;
1841 } else {
1842 Args[i] = argE.get();
1843
1844 // Update the parameter type in-place.
1845 param->setType(paramType);
1846 }
1847 continue;
1848 }
1849
1850 QualType origParamType = param->getType();
1851 QualType paramType = param->getType();
1852 if (typeArgs)
1853 paramType = paramType.substObjCTypeArgs(
1854 Context,
1855 *typeArgs,
1856 ObjCSubstitutionContext::Parameter);
1857
1858 if (RequireCompleteType(argExpr->getSourceRange().getBegin(),
1859 paramType,
1860 diag::err_call_incomplete_argument, argExpr))
1861 return true;
1862
1863 InitializedEntity Entity
1864 = InitializedEntity::InitializeParameter(Context, param, paramType);
1865 ExprResult ArgE = PerformCopyInitialization(Entity, SourceLocation(), argExpr);
1866 if (ArgE.isInvalid())
1867 IsError = true;
1868 else {
1869 Args[i] = ArgE.getAs<Expr>();
1870
1871 // If we are type-erasing a block to a block-compatible
1872 // Objective-C pointer type, we may need to extend the lifetime
1873 // of the block object.
1874 if (typeArgs && Args[i]->isPRValue() && paramType->isBlockPointerType() &&
1875 Args[i]->getType()->isBlockPointerType() &&
1876 origParamType->isObjCObjectPointerType()) {
1877 ExprResult arg = Args[i];
1878 maybeExtendBlockObject(arg);
1879 Args[i] = arg.get();
1880 }
1881 }
1882 }
1883
1884 // Promote additional arguments to variadic methods.
1885 if (Method->isVariadic()) {
1886 for (unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) {
1887 if (Args[i]->isTypeDependent())
1888 continue;
1889
1890 ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod,
1891 nullptr);
1892 IsError |= Arg.isInvalid();
1893 Args[i] = Arg.get();
1894 }
1895 } else {
1896 // Check for extra arguments to non-variadic methods.
1897 if (Args.size() != NumNamedArgs) {
1898 Diag(Args[NumNamedArgs]->getBeginLoc(),
1899 diag::err_typecheck_call_too_many_args)
1900 << 2 /*method*/ << NumNamedArgs << static_cast<unsigned>(Args.size())
1901 << Method->getSourceRange()
1902 << SourceRange(Args[NumNamedArgs]->getBeginLoc(),
1903 Args.back()->getEndLoc());
1904 }
1905 }
1906
1907 DiagnoseSentinelCalls(Method, SelLoc, Args);
1908
1909 // Do additional checkings on method.
1910 IsError |=
1911 CheckObjCMethodCall(Method, SelLoc, ArrayRef(Args.data(), Args.size()));
1912
1913 return IsError;
1914 }
1915
isSelfExpr(Expr * RExpr)1916 bool Sema::isSelfExpr(Expr *RExpr) {
1917 // 'self' is objc 'self' in an objc method only.
1918 ObjCMethodDecl *Method =
1919 dyn_cast_or_null<ObjCMethodDecl>(CurContext->getNonClosureAncestor());
1920 return isSelfExpr(RExpr, Method);
1921 }
1922
isSelfExpr(Expr * receiver,const ObjCMethodDecl * method)1923 bool Sema::isSelfExpr(Expr *receiver, const ObjCMethodDecl *method) {
1924 if (!method) return false;
1925
1926 receiver = receiver->IgnoreParenLValueCasts();
1927 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(receiver))
1928 if (DRE->getDecl() == method->getSelfDecl())
1929 return true;
1930 return false;
1931 }
1932
1933 /// LookupMethodInType - Look up a method in an ObjCObjectType.
LookupMethodInObjectType(Selector sel,QualType type,bool isInstance)1934 ObjCMethodDecl *Sema::LookupMethodInObjectType(Selector sel, QualType type,
1935 bool isInstance) {
1936 const ObjCObjectType *objType = type->castAs<ObjCObjectType>();
1937 if (ObjCInterfaceDecl *iface = objType->getInterface()) {
1938 // Look it up in the main interface (and categories, etc.)
1939 if (ObjCMethodDecl *method = iface->lookupMethod(sel, isInstance))
1940 return method;
1941
1942 // Okay, look for "private" methods declared in any
1943 // @implementations we've seen.
1944 if (ObjCMethodDecl *method = iface->lookupPrivateMethod(sel, isInstance))
1945 return method;
1946 }
1947
1948 // Check qualifiers.
1949 for (const auto *I : objType->quals())
1950 if (ObjCMethodDecl *method = I->lookupMethod(sel, isInstance))
1951 return method;
1952
1953 return nullptr;
1954 }
1955
1956 /// LookupMethodInQualifiedType - Lookups up a method in protocol qualifier
1957 /// list of a qualified objective pointer type.
LookupMethodInQualifiedType(Selector Sel,const ObjCObjectPointerType * OPT,bool Instance)1958 ObjCMethodDecl *Sema::LookupMethodInQualifiedType(Selector Sel,
1959 const ObjCObjectPointerType *OPT,
1960 bool Instance)
1961 {
1962 ObjCMethodDecl *MD = nullptr;
1963 for (const auto *PROTO : OPT->quals()) {
1964 if ((MD = PROTO->lookupMethod(Sel, Instance))) {
1965 return MD;
1966 }
1967 }
1968 return nullptr;
1969 }
1970
1971 /// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an
1972 /// objective C interface. This is a property reference expression.
1973 ExprResult Sema::
HandleExprPropertyRefExpr(const ObjCObjectPointerType * OPT,Expr * BaseExpr,SourceLocation OpLoc,DeclarationName MemberName,SourceLocation MemberLoc,SourceLocation SuperLoc,QualType SuperType,bool Super)1974 HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
1975 Expr *BaseExpr, SourceLocation OpLoc,
1976 DeclarationName MemberName,
1977 SourceLocation MemberLoc,
1978 SourceLocation SuperLoc, QualType SuperType,
1979 bool Super) {
1980 const ObjCInterfaceType *IFaceT = OPT->getInterfaceType();
1981 ObjCInterfaceDecl *IFace = IFaceT->getDecl();
1982
1983 if (!MemberName.isIdentifier()) {
1984 Diag(MemberLoc, diag::err_invalid_property_name)
1985 << MemberName << QualType(OPT, 0);
1986 return ExprError();
1987 }
1988
1989 IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
1990
1991 SourceRange BaseRange = Super? SourceRange(SuperLoc)
1992 : BaseExpr->getSourceRange();
1993 if (RequireCompleteType(MemberLoc, OPT->getPointeeType(),
1994 diag::err_property_not_found_forward_class,
1995 MemberName, BaseRange))
1996 return ExprError();
1997
1998 if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(
1999 Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
2000 // Check whether we can reference this property.
2001 if (DiagnoseUseOfDecl(PD, MemberLoc))
2002 return ExprError();
2003 if (Super)
2004 return new (Context)
2005 ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
2006 OK_ObjCProperty, MemberLoc, SuperLoc, SuperType);
2007 else
2008 return new (Context)
2009 ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
2010 OK_ObjCProperty, MemberLoc, BaseExpr);
2011 }
2012 // Check protocols on qualified interfaces.
2013 for (const auto *I : OPT->quals())
2014 if (ObjCPropertyDecl *PD = I->FindPropertyDeclaration(
2015 Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
2016 // Check whether we can reference this property.
2017 if (DiagnoseUseOfDecl(PD, MemberLoc))
2018 return ExprError();
2019
2020 if (Super)
2021 return new (Context) ObjCPropertyRefExpr(
2022 PD, Context.PseudoObjectTy, VK_LValue, OK_ObjCProperty, MemberLoc,
2023 SuperLoc, SuperType);
2024 else
2025 return new (Context)
2026 ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
2027 OK_ObjCProperty, MemberLoc, BaseExpr);
2028 }
2029 // If that failed, look for an "implicit" property by seeing if the nullary
2030 // selector is implemented.
2031
2032 // FIXME: The logic for looking up nullary and unary selectors should be
2033 // shared with the code in ActOnInstanceMessage.
2034
2035 Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
2036 ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
2037
2038 // May be found in property's qualified list.
2039 if (!Getter)
2040 Getter = LookupMethodInQualifiedType(Sel, OPT, true);
2041
2042 // If this reference is in an @implementation, check for 'private' methods.
2043 if (!Getter)
2044 Getter = IFace->lookupPrivateMethod(Sel);
2045
2046 if (Getter) {
2047 // Check if we can reference this property.
2048 if (DiagnoseUseOfDecl(Getter, MemberLoc))
2049 return ExprError();
2050 }
2051 // If we found a getter then this may be a valid dot-reference, we
2052 // will look for the matching setter, in case it is needed.
2053 Selector SetterSel =
2054 SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
2055 PP.getSelectorTable(), Member);
2056 ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
2057
2058 // May be found in property's qualified list.
2059 if (!Setter)
2060 Setter = LookupMethodInQualifiedType(SetterSel, OPT, true);
2061
2062 if (!Setter) {
2063 // If this reference is in an @implementation, also check for 'private'
2064 // methods.
2065 Setter = IFace->lookupPrivateMethod(SetterSel);
2066 }
2067
2068 if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
2069 return ExprError();
2070
2071 // Special warning if member name used in a property-dot for a setter accessor
2072 // does not use a property with same name; e.g. obj.X = ... for a property with
2073 // name 'x'.
2074 if (Setter && Setter->isImplicit() && Setter->isPropertyAccessor() &&
2075 !IFace->FindPropertyDeclaration(
2076 Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
2077 if (const ObjCPropertyDecl *PDecl = Setter->findPropertyDecl()) {
2078 // Do not warn if user is using property-dot syntax to make call to
2079 // user named setter.
2080 if (!(PDecl->getPropertyAttributes() &
2081 ObjCPropertyAttribute::kind_setter))
2082 Diag(MemberLoc,
2083 diag::warn_property_access_suggest)
2084 << MemberName << QualType(OPT, 0) << PDecl->getName()
2085 << FixItHint::CreateReplacement(MemberLoc, PDecl->getName());
2086 }
2087 }
2088
2089 if (Getter || Setter) {
2090 if (Super)
2091 return new (Context)
2092 ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
2093 OK_ObjCProperty, MemberLoc, SuperLoc, SuperType);
2094 else
2095 return new (Context)
2096 ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
2097 OK_ObjCProperty, MemberLoc, BaseExpr);
2098
2099 }
2100
2101 // Attempt to correct for typos in property names.
2102 DeclFilterCCC<ObjCPropertyDecl> CCC{};
2103 if (TypoCorrection Corrected = CorrectTypo(
2104 DeclarationNameInfo(MemberName, MemberLoc), LookupOrdinaryName,
2105 nullptr, nullptr, CCC, CTK_ErrorRecovery, IFace, false, OPT)) {
2106 DeclarationName TypoResult = Corrected.getCorrection();
2107 if (TypoResult.isIdentifier() &&
2108 TypoResult.getAsIdentifierInfo() == Member) {
2109 // There is no need to try the correction if it is the same.
2110 NamedDecl *ChosenDecl =
2111 Corrected.isKeyword() ? nullptr : Corrected.getFoundDecl();
2112 if (ChosenDecl && isa<ObjCPropertyDecl>(ChosenDecl))
2113 if (cast<ObjCPropertyDecl>(ChosenDecl)->isClassProperty()) {
2114 // This is a class property, we should not use the instance to
2115 // access it.
2116 Diag(MemberLoc, diag::err_class_property_found) << MemberName
2117 << OPT->getInterfaceDecl()->getName()
2118 << FixItHint::CreateReplacement(BaseExpr->getSourceRange(),
2119 OPT->getInterfaceDecl()->getName());
2120 return ExprError();
2121 }
2122 } else {
2123 diagnoseTypo(Corrected, PDiag(diag::err_property_not_found_suggest)
2124 << MemberName << QualType(OPT, 0));
2125 return HandleExprPropertyRefExpr(OPT, BaseExpr, OpLoc,
2126 TypoResult, MemberLoc,
2127 SuperLoc, SuperType, Super);
2128 }
2129 }
2130 ObjCInterfaceDecl *ClassDeclared;
2131 if (ObjCIvarDecl *Ivar =
2132 IFace->lookupInstanceVariable(Member, ClassDeclared)) {
2133 QualType T = Ivar->getType();
2134 if (const ObjCObjectPointerType * OBJPT =
2135 T->getAsObjCInterfacePointerType()) {
2136 if (RequireCompleteType(MemberLoc, OBJPT->getPointeeType(),
2137 diag::err_property_not_as_forward_class,
2138 MemberName, BaseExpr))
2139 return ExprError();
2140 }
2141 Diag(MemberLoc,
2142 diag::err_ivar_access_using_property_syntax_suggest)
2143 << MemberName << QualType(OPT, 0) << Ivar->getDeclName()
2144 << FixItHint::CreateReplacement(OpLoc, "->");
2145 return ExprError();
2146 }
2147
2148 Diag(MemberLoc, diag::err_property_not_found)
2149 << MemberName << QualType(OPT, 0);
2150 if (Setter)
2151 Diag(Setter->getLocation(), diag::note_getter_unavailable)
2152 << MemberName << BaseExpr->getSourceRange();
2153 return ExprError();
2154 }
2155
2156 ExprResult Sema::
ActOnClassPropertyRefExpr(IdentifierInfo & receiverName,IdentifierInfo & propertyName,SourceLocation receiverNameLoc,SourceLocation propertyNameLoc)2157 ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
2158 IdentifierInfo &propertyName,
2159 SourceLocation receiverNameLoc,
2160 SourceLocation propertyNameLoc) {
2161
2162 IdentifierInfo *receiverNamePtr = &receiverName;
2163 ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(receiverNamePtr,
2164 receiverNameLoc);
2165
2166 QualType SuperType;
2167 if (!IFace) {
2168 // If the "receiver" is 'super' in a method, handle it as an expression-like
2169 // property reference.
2170 if (receiverNamePtr->isStr("super")) {
2171 if (ObjCMethodDecl *CurMethod = tryCaptureObjCSelf(receiverNameLoc)) {
2172 if (auto classDecl = CurMethod->getClassInterface()) {
2173 SuperType = QualType(classDecl->getSuperClassType(), 0);
2174 if (CurMethod->isInstanceMethod()) {
2175 if (SuperType.isNull()) {
2176 // The current class does not have a superclass.
2177 Diag(receiverNameLoc, diag::err_root_class_cannot_use_super)
2178 << CurMethod->getClassInterface()->getIdentifier();
2179 return ExprError();
2180 }
2181 QualType T = Context.getObjCObjectPointerType(SuperType);
2182
2183 return HandleExprPropertyRefExpr(T->castAs<ObjCObjectPointerType>(),
2184 /*BaseExpr*/nullptr,
2185 SourceLocation()/*OpLoc*/,
2186 &propertyName,
2187 propertyNameLoc,
2188 receiverNameLoc, T, true);
2189 }
2190
2191 // Otherwise, if this is a class method, try dispatching to our
2192 // superclass.
2193 IFace = CurMethod->getClassInterface()->getSuperClass();
2194 }
2195 }
2196 }
2197
2198 if (!IFace) {
2199 Diag(receiverNameLoc, diag::err_expected_either) << tok::identifier
2200 << tok::l_paren;
2201 return ExprError();
2202 }
2203 }
2204
2205 Selector GetterSel;
2206 Selector SetterSel;
2207 if (auto PD = IFace->FindPropertyDeclaration(
2208 &propertyName, ObjCPropertyQueryKind::OBJC_PR_query_class)) {
2209 GetterSel = PD->getGetterName();
2210 SetterSel = PD->getSetterName();
2211 } else {
2212 GetterSel = PP.getSelectorTable().getNullarySelector(&propertyName);
2213 SetterSel = SelectorTable::constructSetterSelector(
2214 PP.getIdentifierTable(), PP.getSelectorTable(), &propertyName);
2215 }
2216
2217 // Search for a declared property first.
2218 ObjCMethodDecl *Getter = IFace->lookupClassMethod(GetterSel);
2219
2220 // If this reference is in an @implementation, check for 'private' methods.
2221 if (!Getter)
2222 Getter = IFace->lookupPrivateClassMethod(GetterSel);
2223
2224 if (Getter) {
2225 // FIXME: refactor/share with ActOnMemberReference().
2226 // Check if we can reference this property.
2227 if (DiagnoseUseOfDecl(Getter, propertyNameLoc))
2228 return ExprError();
2229 }
2230
2231 // Look for the matching setter, in case it is needed.
2232 ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
2233 if (!Setter) {
2234 // If this reference is in an @implementation, also check for 'private'
2235 // methods.
2236 Setter = IFace->lookupPrivateClassMethod(SetterSel);
2237 }
2238 // Look through local category implementations associated with the class.
2239 if (!Setter)
2240 Setter = IFace->getCategoryClassMethod(SetterSel);
2241
2242 if (Setter && DiagnoseUseOfDecl(Setter, propertyNameLoc))
2243 return ExprError();
2244
2245 if (Getter || Setter) {
2246 if (!SuperType.isNull())
2247 return new (Context)
2248 ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
2249 OK_ObjCProperty, propertyNameLoc, receiverNameLoc,
2250 SuperType);
2251
2252 return new (Context) ObjCPropertyRefExpr(
2253 Getter, Setter, Context.PseudoObjectTy, VK_LValue, OK_ObjCProperty,
2254 propertyNameLoc, receiverNameLoc, IFace);
2255 }
2256 return ExprError(Diag(propertyNameLoc, diag::err_property_not_found)
2257 << &propertyName << Context.getObjCInterfaceType(IFace));
2258 }
2259
2260 namespace {
2261
2262 class ObjCInterfaceOrSuperCCC final : public CorrectionCandidateCallback {
2263 public:
ObjCInterfaceOrSuperCCC(ObjCMethodDecl * Method)2264 ObjCInterfaceOrSuperCCC(ObjCMethodDecl *Method) {
2265 // Determine whether "super" is acceptable in the current context.
2266 if (Method && Method->getClassInterface())
2267 WantObjCSuper = Method->getClassInterface()->getSuperClass();
2268 }
2269
ValidateCandidate(const TypoCorrection & candidate)2270 bool ValidateCandidate(const TypoCorrection &candidate) override {
2271 return candidate.getCorrectionDeclAs<ObjCInterfaceDecl>() ||
2272 candidate.isKeyword("super");
2273 }
2274
clone()2275 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2276 return std::make_unique<ObjCInterfaceOrSuperCCC>(*this);
2277 }
2278 };
2279
2280 } // end anonymous namespace
2281
getObjCMessageKind(Scope * S,IdentifierInfo * Name,SourceLocation NameLoc,bool IsSuper,bool HasTrailingDot,ParsedType & ReceiverType)2282 Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
2283 IdentifierInfo *Name,
2284 SourceLocation NameLoc,
2285 bool IsSuper,
2286 bool HasTrailingDot,
2287 ParsedType &ReceiverType) {
2288 ReceiverType = nullptr;
2289
2290 // If the identifier is "super" and there is no trailing dot, we're
2291 // messaging super. If the identifier is "super" and there is a
2292 // trailing dot, it's an instance message.
2293 if (IsSuper && S->isInObjcMethodScope())
2294 return HasTrailingDot? ObjCInstanceMessage : ObjCSuperMessage;
2295
2296 LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName);
2297 LookupName(Result, S);
2298
2299 switch (Result.getResultKind()) {
2300 case LookupResult::NotFound:
2301 // Normal name lookup didn't find anything. If we're in an
2302 // Objective-C method, look for ivars. If we find one, we're done!
2303 // FIXME: This is a hack. Ivar lookup should be part of normal
2304 // lookup.
2305 if (ObjCMethodDecl *Method = getCurMethodDecl()) {
2306 if (!Method->getClassInterface()) {
2307 // Fall back: let the parser try to parse it as an instance message.
2308 return ObjCInstanceMessage;
2309 }
2310
2311 ObjCInterfaceDecl *ClassDeclared;
2312 if (Method->getClassInterface()->lookupInstanceVariable(Name,
2313 ClassDeclared))
2314 return ObjCInstanceMessage;
2315 }
2316
2317 // Break out; we'll perform typo correction below.
2318 break;
2319
2320 case LookupResult::NotFoundInCurrentInstantiation:
2321 case LookupResult::FoundOverloaded:
2322 case LookupResult::FoundUnresolvedValue:
2323 case LookupResult::Ambiguous:
2324 Result.suppressDiagnostics();
2325 return ObjCInstanceMessage;
2326
2327 case LookupResult::Found: {
2328 // If the identifier is a class or not, and there is a trailing dot,
2329 // it's an instance message.
2330 if (HasTrailingDot)
2331 return ObjCInstanceMessage;
2332 // We found something. If it's a type, then we have a class
2333 // message. Otherwise, it's an instance message.
2334 NamedDecl *ND = Result.getFoundDecl();
2335 QualType T;
2336 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(ND))
2337 T = Context.getObjCInterfaceType(Class);
2338 else if (TypeDecl *Type = dyn_cast<TypeDecl>(ND)) {
2339 T = Context.getTypeDeclType(Type);
2340 DiagnoseUseOfDecl(Type, NameLoc);
2341 }
2342 else
2343 return ObjCInstanceMessage;
2344
2345 // We have a class message, and T is the type we're
2346 // messaging. Build source-location information for it.
2347 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
2348 ReceiverType = CreateParsedType(T, TSInfo);
2349 return ObjCClassMessage;
2350 }
2351 }
2352
2353 ObjCInterfaceOrSuperCCC CCC(getCurMethodDecl());
2354 if (TypoCorrection Corrected = CorrectTypo(
2355 Result.getLookupNameInfo(), Result.getLookupKind(), S, nullptr, CCC,
2356 CTK_ErrorRecovery, nullptr, false, nullptr, false)) {
2357 if (Corrected.isKeyword()) {
2358 // If we've found the keyword "super" (the only keyword that would be
2359 // returned by CorrectTypo), this is a send to super.
2360 diagnoseTypo(Corrected,
2361 PDiag(diag::err_unknown_receiver_suggest) << Name);
2362 return ObjCSuperMessage;
2363 } else if (ObjCInterfaceDecl *Class =
2364 Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) {
2365 // If we found a declaration, correct when it refers to an Objective-C
2366 // class.
2367 diagnoseTypo(Corrected,
2368 PDiag(diag::err_unknown_receiver_suggest) << Name);
2369 QualType T = Context.getObjCInterfaceType(Class);
2370 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
2371 ReceiverType = CreateParsedType(T, TSInfo);
2372 return ObjCClassMessage;
2373 }
2374 }
2375
2376 // Fall back: let the parser try to parse it as an instance message.
2377 return ObjCInstanceMessage;
2378 }
2379
ActOnSuperMessage(Scope * S,SourceLocation SuperLoc,Selector Sel,SourceLocation LBracLoc,ArrayRef<SourceLocation> SelectorLocs,SourceLocation RBracLoc,MultiExprArg Args)2380 ExprResult Sema::ActOnSuperMessage(Scope *S,
2381 SourceLocation SuperLoc,
2382 Selector Sel,
2383 SourceLocation LBracLoc,
2384 ArrayRef<SourceLocation> SelectorLocs,
2385 SourceLocation RBracLoc,
2386 MultiExprArg Args) {
2387 // Determine whether we are inside a method or not.
2388 ObjCMethodDecl *Method = tryCaptureObjCSelf(SuperLoc);
2389 if (!Method) {
2390 Diag(SuperLoc, diag::err_invalid_receiver_to_message_super);
2391 return ExprError();
2392 }
2393
2394 ObjCInterfaceDecl *Class = Method->getClassInterface();
2395 if (!Class) {
2396 Diag(SuperLoc, diag::err_no_super_class_message)
2397 << Method->getDeclName();
2398 return ExprError();
2399 }
2400
2401 QualType SuperTy(Class->getSuperClassType(), 0);
2402 if (SuperTy.isNull()) {
2403 // The current class does not have a superclass.
2404 Diag(SuperLoc, diag::err_root_class_cannot_use_super)
2405 << Class->getIdentifier();
2406 return ExprError();
2407 }
2408
2409 // We are in a method whose class has a superclass, so 'super'
2410 // is acting as a keyword.
2411 if (Method->getSelector() == Sel)
2412 getCurFunction()->ObjCShouldCallSuper = false;
2413
2414 if (Method->isInstanceMethod()) {
2415 // Since we are in an instance method, this is an instance
2416 // message to the superclass instance.
2417 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2418 return BuildInstanceMessage(nullptr, SuperTy, SuperLoc,
2419 Sel, /*Method=*/nullptr,
2420 LBracLoc, SelectorLocs, RBracLoc, Args);
2421 }
2422
2423 // Since we are in a class method, this is a class message to
2424 // the superclass.
2425 return BuildClassMessage(/*ReceiverTypeInfo=*/nullptr,
2426 SuperTy,
2427 SuperLoc, Sel, /*Method=*/nullptr,
2428 LBracLoc, SelectorLocs, RBracLoc, Args);
2429 }
2430
BuildClassMessageImplicit(QualType ReceiverType,bool isSuperReceiver,SourceLocation Loc,Selector Sel,ObjCMethodDecl * Method,MultiExprArg Args)2431 ExprResult Sema::BuildClassMessageImplicit(QualType ReceiverType,
2432 bool isSuperReceiver,
2433 SourceLocation Loc,
2434 Selector Sel,
2435 ObjCMethodDecl *Method,
2436 MultiExprArg Args) {
2437 TypeSourceInfo *receiverTypeInfo = nullptr;
2438 if (!ReceiverType.isNull())
2439 receiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType);
2440
2441 return BuildClassMessage(receiverTypeInfo, ReceiverType,
2442 /*SuperLoc=*/isSuperReceiver ? Loc : SourceLocation(),
2443 Sel, Method, Loc, Loc, Loc, Args,
2444 /*isImplicit=*/true);
2445 }
2446
applyCocoaAPICheck(Sema & S,const ObjCMessageExpr * Msg,unsigned DiagID,bool (* refactor)(const ObjCMessageExpr *,const NSAPI &,edit::Commit &))2447 static void applyCocoaAPICheck(Sema &S, const ObjCMessageExpr *Msg,
2448 unsigned DiagID,
2449 bool (*refactor)(const ObjCMessageExpr *,
2450 const NSAPI &, edit::Commit &)) {
2451 SourceLocation MsgLoc = Msg->getExprLoc();
2452 if (S.Diags.isIgnored(DiagID, MsgLoc))
2453 return;
2454
2455 SourceManager &SM = S.SourceMgr;
2456 edit::Commit ECommit(SM, S.LangOpts);
2457 if (refactor(Msg,*S.NSAPIObj, ECommit)) {
2458 auto Builder = S.Diag(MsgLoc, DiagID)
2459 << Msg->getSelector() << Msg->getSourceRange();
2460 // FIXME: Don't emit diagnostic at all if fixits are non-commitable.
2461 if (!ECommit.isCommitable())
2462 return;
2463 for (edit::Commit::edit_iterator
2464 I = ECommit.edit_begin(), E = ECommit.edit_end(); I != E; ++I) {
2465 const edit::Commit::Edit &Edit = *I;
2466 switch (Edit.Kind) {
2467 case edit::Commit::Act_Insert:
2468 Builder.AddFixItHint(FixItHint::CreateInsertion(Edit.OrigLoc,
2469 Edit.Text,
2470 Edit.BeforePrev));
2471 break;
2472 case edit::Commit::Act_InsertFromRange:
2473 Builder.AddFixItHint(
2474 FixItHint::CreateInsertionFromRange(Edit.OrigLoc,
2475 Edit.getInsertFromRange(SM),
2476 Edit.BeforePrev));
2477 break;
2478 case edit::Commit::Act_Remove:
2479 Builder.AddFixItHint(FixItHint::CreateRemoval(Edit.getFileRange(SM)));
2480 break;
2481 }
2482 }
2483 }
2484 }
2485
checkCocoaAPI(Sema & S,const ObjCMessageExpr * Msg)2486 static void checkCocoaAPI(Sema &S, const ObjCMessageExpr *Msg) {
2487 applyCocoaAPICheck(S, Msg, diag::warn_objc_redundant_literal_use,
2488 edit::rewriteObjCRedundantCallWithLiteral);
2489 }
2490
checkFoundationAPI(Sema & S,SourceLocation Loc,const ObjCMethodDecl * Method,ArrayRef<Expr * > Args,QualType ReceiverType,bool IsClassObjectCall)2491 static void checkFoundationAPI(Sema &S, SourceLocation Loc,
2492 const ObjCMethodDecl *Method,
2493 ArrayRef<Expr *> Args, QualType ReceiverType,
2494 bool IsClassObjectCall) {
2495 // Check if this is a performSelector method that uses a selector that returns
2496 // a record or a vector type.
2497 if (Method->getSelector().getMethodFamily() != OMF_performSelector ||
2498 Args.empty())
2499 return;
2500 const auto *SE = dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens());
2501 if (!SE)
2502 return;
2503 ObjCMethodDecl *ImpliedMethod;
2504 if (!IsClassObjectCall) {
2505 const auto *OPT = ReceiverType->getAs<ObjCObjectPointerType>();
2506 if (!OPT || !OPT->getInterfaceDecl())
2507 return;
2508 ImpliedMethod =
2509 OPT->getInterfaceDecl()->lookupInstanceMethod(SE->getSelector());
2510 if (!ImpliedMethod)
2511 ImpliedMethod =
2512 OPT->getInterfaceDecl()->lookupPrivateMethod(SE->getSelector());
2513 } else {
2514 const auto *IT = ReceiverType->getAs<ObjCInterfaceType>();
2515 if (!IT)
2516 return;
2517 ImpliedMethod = IT->getDecl()->lookupClassMethod(SE->getSelector());
2518 if (!ImpliedMethod)
2519 ImpliedMethod =
2520 IT->getDecl()->lookupPrivateClassMethod(SE->getSelector());
2521 }
2522 if (!ImpliedMethod)
2523 return;
2524 QualType Ret = ImpliedMethod->getReturnType();
2525 if (Ret->isRecordType() || Ret->isVectorType() || Ret->isExtVectorType()) {
2526 S.Diag(Loc, diag::warn_objc_unsafe_perform_selector)
2527 << Method->getSelector()
2528 << (!Ret->isRecordType()
2529 ? /*Vector*/ 2
2530 : Ret->isUnionType() ? /*Union*/ 1 : /*Struct*/ 0);
2531 S.Diag(ImpliedMethod->getBeginLoc(),
2532 diag::note_objc_unsafe_perform_selector_method_declared_here)
2533 << ImpliedMethod->getSelector() << Ret;
2534 }
2535 }
2536
2537 /// Diagnose use of %s directive in an NSString which is being passed
2538 /// as formatting string to formatting method.
2539 static void
DiagnoseCStringFormatDirectiveInObjCAPI(Sema & S,ObjCMethodDecl * Method,Selector Sel,Expr ** Args,unsigned NumArgs)2540 DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S,
2541 ObjCMethodDecl *Method,
2542 Selector Sel,
2543 Expr **Args, unsigned NumArgs) {
2544 unsigned Idx = 0;
2545 bool Format = false;
2546 ObjCStringFormatFamily SFFamily = Sel.getStringFormatFamily();
2547 if (SFFamily == ObjCStringFormatFamily::SFF_NSString) {
2548 Idx = 0;
2549 Format = true;
2550 }
2551 else if (Method) {
2552 for (const auto *I : Method->specific_attrs<FormatAttr>()) {
2553 if (S.GetFormatNSStringIdx(I, Idx)) {
2554 Format = true;
2555 break;
2556 }
2557 }
2558 }
2559 if (!Format || NumArgs <= Idx)
2560 return;
2561
2562 Expr *FormatExpr = Args[Idx];
2563 if (ObjCStringLiteral *OSL =
2564 dyn_cast<ObjCStringLiteral>(FormatExpr->IgnoreParenImpCasts())) {
2565 StringLiteral *FormatString = OSL->getString();
2566 if (S.FormatStringHasSArg(FormatString)) {
2567 S.Diag(FormatExpr->getExprLoc(), diag::warn_objc_cdirective_format_string)
2568 << "%s" << 0 << 0;
2569 if (Method)
2570 S.Diag(Method->getLocation(), diag::note_method_declared_at)
2571 << Method->getDeclName();
2572 }
2573 }
2574 }
2575
2576 /// Build an Objective-C class message expression.
2577 ///
2578 /// This routine takes care of both normal class messages and
2579 /// class messages to the superclass.
2580 ///
2581 /// \param ReceiverTypeInfo Type source information that describes the
2582 /// receiver of this message. This may be NULL, in which case we are
2583 /// sending to the superclass and \p SuperLoc must be a valid source
2584 /// location.
2585
2586 /// \param ReceiverType The type of the object receiving the
2587 /// message. When \p ReceiverTypeInfo is non-NULL, this is the same
2588 /// type as that refers to. For a superclass send, this is the type of
2589 /// the superclass.
2590 ///
2591 /// \param SuperLoc The location of the "super" keyword in a
2592 /// superclass message.
2593 ///
2594 /// \param Sel The selector to which the message is being sent.
2595 ///
2596 /// \param Method The method that this class message is invoking, if
2597 /// already known.
2598 ///
2599 /// \param LBracLoc The location of the opening square bracket ']'.
2600 ///
2601 /// \param RBracLoc The location of the closing square bracket ']'.
2602 ///
2603 /// \param ArgsIn The message arguments.
BuildClassMessage(TypeSourceInfo * ReceiverTypeInfo,QualType ReceiverType,SourceLocation SuperLoc,Selector Sel,ObjCMethodDecl * Method,SourceLocation LBracLoc,ArrayRef<SourceLocation> SelectorLocs,SourceLocation RBracLoc,MultiExprArg ArgsIn,bool isImplicit)2604 ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
2605 QualType ReceiverType,
2606 SourceLocation SuperLoc,
2607 Selector Sel,
2608 ObjCMethodDecl *Method,
2609 SourceLocation LBracLoc,
2610 ArrayRef<SourceLocation> SelectorLocs,
2611 SourceLocation RBracLoc,
2612 MultiExprArg ArgsIn,
2613 bool isImplicit) {
2614 SourceLocation Loc = SuperLoc.isValid()? SuperLoc
2615 : ReceiverTypeInfo->getTypeLoc().getSourceRange().getBegin();
2616 if (LBracLoc.isInvalid()) {
2617 Diag(Loc, diag::err_missing_open_square_message_send)
2618 << FixItHint::CreateInsertion(Loc, "[");
2619 LBracLoc = Loc;
2620 }
2621 ArrayRef<SourceLocation> SelectorSlotLocs;
2622 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2623 SelectorSlotLocs = SelectorLocs;
2624 else
2625 SelectorSlotLocs = Loc;
2626 SourceLocation SelLoc = SelectorSlotLocs.front();
2627
2628 if (ReceiverType->isDependentType()) {
2629 // If the receiver type is dependent, we can't type-check anything
2630 // at this point. Build a dependent expression.
2631 unsigned NumArgs = ArgsIn.size();
2632 Expr **Args = ArgsIn.data();
2633 assert(SuperLoc.isInvalid() && "Message to super with dependent type");
2634 return ObjCMessageExpr::Create(Context, ReceiverType, VK_PRValue, LBracLoc,
2635 ReceiverTypeInfo, Sel, SelectorLocs,
2636 /*Method=*/nullptr, ArrayRef(Args, NumArgs),
2637 RBracLoc, isImplicit);
2638 }
2639
2640 // Find the class to which we are sending this message.
2641 ObjCInterfaceDecl *Class = nullptr;
2642 const ObjCObjectType *ClassType = ReceiverType->getAs<ObjCObjectType>();
2643 if (!ClassType || !(Class = ClassType->getInterface())) {
2644 Diag(Loc, diag::err_invalid_receiver_class_message)
2645 << ReceiverType;
2646 return ExprError();
2647 }
2648 assert(Class && "We don't know which class we're messaging?");
2649 // objc++ diagnoses during typename annotation.
2650 if (!getLangOpts().CPlusPlus)
2651 (void)DiagnoseUseOfDecl(Class, SelectorSlotLocs);
2652 // Find the method we are messaging.
2653 if (!Method) {
2654 SourceRange TypeRange
2655 = SuperLoc.isValid()? SourceRange(SuperLoc)
2656 : ReceiverTypeInfo->getTypeLoc().getSourceRange();
2657 if (RequireCompleteType(Loc, Context.getObjCInterfaceType(Class),
2658 (getLangOpts().ObjCAutoRefCount
2659 ? diag::err_arc_receiver_forward_class
2660 : diag::warn_receiver_forward_class),
2661 TypeRange)) {
2662 // A forward class used in messaging is treated as a 'Class'
2663 Method = LookupFactoryMethodInGlobalPool(Sel,
2664 SourceRange(LBracLoc, RBracLoc));
2665 if (Method && !getLangOpts().ObjCAutoRefCount)
2666 Diag(Method->getLocation(), diag::note_method_sent_forward_class)
2667 << Method->getDeclName();
2668 }
2669 if (!Method)
2670 Method = Class->lookupClassMethod(Sel);
2671
2672 // If we have an implementation in scope, check "private" methods.
2673 if (!Method)
2674 Method = Class->lookupPrivateClassMethod(Sel);
2675
2676 if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs,
2677 nullptr, false, false, Class))
2678 return ExprError();
2679 }
2680
2681 // Check the argument types and determine the result type.
2682 QualType ReturnType;
2683 ExprValueKind VK = VK_PRValue;
2684
2685 unsigned NumArgs = ArgsIn.size();
2686 Expr **Args = ArgsIn.data();
2687 if (CheckMessageArgumentTypes(/*Receiver=*/nullptr, ReceiverType,
2688 MultiExprArg(Args, NumArgs), Sel, SelectorLocs,
2689 Method, true, SuperLoc.isValid(), LBracLoc,
2690 RBracLoc, SourceRange(), ReturnType, VK))
2691 return ExprError();
2692
2693 if (Method && !Method->getReturnType()->isVoidType() &&
2694 RequireCompleteType(LBracLoc, Method->getReturnType(),
2695 diag::err_illegal_message_expr_incomplete_type))
2696 return ExprError();
2697
2698 if (Method && Method->isDirectMethod() && SuperLoc.isValid()) {
2699 Diag(SuperLoc, diag::err_messaging_super_with_direct_method)
2700 << FixItHint::CreateReplacement(
2701 SuperLoc, getLangOpts().ObjCAutoRefCount
2702 ? "self"
2703 : Method->getClassInterface()->getName());
2704 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
2705 << Method->getDeclName();
2706 }
2707
2708 // Warn about explicit call of +initialize on its own class. But not on 'super'.
2709 if (Method && Method->getMethodFamily() == OMF_initialize) {
2710 if (!SuperLoc.isValid()) {
2711 const ObjCInterfaceDecl *ID =
2712 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext());
2713 if (ID == Class) {
2714 Diag(Loc, diag::warn_direct_initialize_call);
2715 Diag(Method->getLocation(), diag::note_method_declared_at)
2716 << Method->getDeclName();
2717 }
2718 }
2719 else if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
2720 // [super initialize] is allowed only within an +initialize implementation
2721 if (CurMeth->getMethodFamily() != OMF_initialize) {
2722 Diag(Loc, diag::warn_direct_super_initialize_call);
2723 Diag(Method->getLocation(), diag::note_method_declared_at)
2724 << Method->getDeclName();
2725 Diag(CurMeth->getLocation(), diag::note_method_declared_at)
2726 << CurMeth->getDeclName();
2727 }
2728 }
2729 }
2730
2731 DiagnoseCStringFormatDirectiveInObjCAPI(*this, Method, Sel, Args, NumArgs);
2732
2733 // Construct the appropriate ObjCMessageExpr.
2734 ObjCMessageExpr *Result;
2735 if (SuperLoc.isValid())
2736 Result = ObjCMessageExpr::Create(
2737 Context, ReturnType, VK, LBracLoc, SuperLoc, /*IsInstanceSuper=*/false,
2738 ReceiverType, Sel, SelectorLocs, Method, ArrayRef(Args, NumArgs),
2739 RBracLoc, isImplicit);
2740 else {
2741 Result = ObjCMessageExpr::Create(
2742 Context, ReturnType, VK, LBracLoc, ReceiverTypeInfo, Sel, SelectorLocs,
2743 Method, ArrayRef(Args, NumArgs), RBracLoc, isImplicit);
2744 if (!isImplicit)
2745 checkCocoaAPI(*this, Result);
2746 }
2747 if (Method)
2748 checkFoundationAPI(*this, SelLoc, Method, ArrayRef(Args, NumArgs),
2749 ReceiverType, /*IsClassObjectCall=*/true);
2750 return MaybeBindToTemporary(Result);
2751 }
2752
2753 // ActOnClassMessage - used for both unary and keyword messages.
2754 // ArgExprs is optional - if it is present, the number of expressions
2755 // is obtained from Sel.getNumArgs().
ActOnClassMessage(Scope * S,ParsedType Receiver,Selector Sel,SourceLocation LBracLoc,ArrayRef<SourceLocation> SelectorLocs,SourceLocation RBracLoc,MultiExprArg Args)2756 ExprResult Sema::ActOnClassMessage(Scope *S,
2757 ParsedType Receiver,
2758 Selector Sel,
2759 SourceLocation LBracLoc,
2760 ArrayRef<SourceLocation> SelectorLocs,
2761 SourceLocation RBracLoc,
2762 MultiExprArg Args) {
2763 TypeSourceInfo *ReceiverTypeInfo;
2764 QualType ReceiverType = GetTypeFromParser(Receiver, &ReceiverTypeInfo);
2765 if (ReceiverType.isNull())
2766 return ExprError();
2767
2768 if (!ReceiverTypeInfo)
2769 ReceiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType, LBracLoc);
2770
2771 return BuildClassMessage(ReceiverTypeInfo, ReceiverType,
2772 /*SuperLoc=*/SourceLocation(), Sel,
2773 /*Method=*/nullptr, LBracLoc, SelectorLocs, RBracLoc,
2774 Args);
2775 }
2776
BuildInstanceMessageImplicit(Expr * Receiver,QualType ReceiverType,SourceLocation Loc,Selector Sel,ObjCMethodDecl * Method,MultiExprArg Args)2777 ExprResult Sema::BuildInstanceMessageImplicit(Expr *Receiver,
2778 QualType ReceiverType,
2779 SourceLocation Loc,
2780 Selector Sel,
2781 ObjCMethodDecl *Method,
2782 MultiExprArg Args) {
2783 return BuildInstanceMessage(Receiver, ReceiverType,
2784 /*SuperLoc=*/!Receiver ? Loc : SourceLocation(),
2785 Sel, Method, Loc, Loc, Loc, Args,
2786 /*isImplicit=*/true);
2787 }
2788
isMethodDeclaredInRootProtocol(Sema & S,const ObjCMethodDecl * M)2789 static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M) {
2790 if (!S.NSAPIObj)
2791 return false;
2792 const auto *Protocol = dyn_cast<ObjCProtocolDecl>(M->getDeclContext());
2793 if (!Protocol)
2794 return false;
2795 const IdentifierInfo *II = S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject);
2796 if (const auto *RootClass = dyn_cast_or_null<ObjCInterfaceDecl>(
2797 S.LookupSingleName(S.TUScope, II, Protocol->getBeginLoc(),
2798 Sema::LookupOrdinaryName))) {
2799 for (const ObjCProtocolDecl *P : RootClass->all_referenced_protocols()) {
2800 if (P->getCanonicalDecl() == Protocol->getCanonicalDecl())
2801 return true;
2802 }
2803 }
2804 return false;
2805 }
2806
2807 /// Build an Objective-C instance message expression.
2808 ///
2809 /// This routine takes care of both normal instance messages and
2810 /// instance messages to the superclass instance.
2811 ///
2812 /// \param Receiver The expression that computes the object that will
2813 /// receive this message. This may be empty, in which case we are
2814 /// sending to the superclass instance and \p SuperLoc must be a valid
2815 /// source location.
2816 ///
2817 /// \param ReceiverType The (static) type of the object receiving the
2818 /// message. When a \p Receiver expression is provided, this is the
2819 /// same type as that expression. For a superclass instance send, this
2820 /// is a pointer to the type of the superclass.
2821 ///
2822 /// \param SuperLoc The location of the "super" keyword in a
2823 /// superclass instance message.
2824 ///
2825 /// \param Sel The selector to which the message is being sent.
2826 ///
2827 /// \param Method The method that this instance message is invoking, if
2828 /// already known.
2829 ///
2830 /// \param LBracLoc The location of the opening square bracket ']'.
2831 ///
2832 /// \param RBracLoc The location of the closing square bracket ']'.
2833 ///
2834 /// \param ArgsIn The message arguments.
BuildInstanceMessage(Expr * Receiver,QualType ReceiverType,SourceLocation SuperLoc,Selector Sel,ObjCMethodDecl * Method,SourceLocation LBracLoc,ArrayRef<SourceLocation> SelectorLocs,SourceLocation RBracLoc,MultiExprArg ArgsIn,bool isImplicit)2835 ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
2836 QualType ReceiverType,
2837 SourceLocation SuperLoc,
2838 Selector Sel,
2839 ObjCMethodDecl *Method,
2840 SourceLocation LBracLoc,
2841 ArrayRef<SourceLocation> SelectorLocs,
2842 SourceLocation RBracLoc,
2843 MultiExprArg ArgsIn,
2844 bool isImplicit) {
2845 assert((Receiver || SuperLoc.isValid()) && "If the Receiver is null, the "
2846 "SuperLoc must be valid so we can "
2847 "use it instead.");
2848
2849 // The location of the receiver.
2850 SourceLocation Loc = SuperLoc.isValid() ? SuperLoc : Receiver->getBeginLoc();
2851 SourceRange RecRange =
2852 SuperLoc.isValid()? SuperLoc : Receiver->getSourceRange();
2853 ArrayRef<SourceLocation> SelectorSlotLocs;
2854 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2855 SelectorSlotLocs = SelectorLocs;
2856 else
2857 SelectorSlotLocs = Loc;
2858 SourceLocation SelLoc = SelectorSlotLocs.front();
2859
2860 if (LBracLoc.isInvalid()) {
2861 Diag(Loc, diag::err_missing_open_square_message_send)
2862 << FixItHint::CreateInsertion(Loc, "[");
2863 LBracLoc = Loc;
2864 }
2865
2866 // If we have a receiver expression, perform appropriate promotions
2867 // and determine receiver type.
2868 if (Receiver) {
2869 if (Receiver->hasPlaceholderType()) {
2870 ExprResult Result;
2871 if (Receiver->getType() == Context.UnknownAnyTy)
2872 Result = forceUnknownAnyToType(Receiver, Context.getObjCIdType());
2873 else
2874 Result = CheckPlaceholderExpr(Receiver);
2875 if (Result.isInvalid()) return ExprError();
2876 Receiver = Result.get();
2877 }
2878
2879 if (Receiver->isTypeDependent()) {
2880 // If the receiver is type-dependent, we can't type-check anything
2881 // at this point. Build a dependent expression.
2882 unsigned NumArgs = ArgsIn.size();
2883 Expr **Args = ArgsIn.data();
2884 assert(SuperLoc.isInvalid() && "Message to super with dependent type");
2885 return ObjCMessageExpr::Create(
2886 Context, Context.DependentTy, VK_PRValue, LBracLoc, Receiver, Sel,
2887 SelectorLocs, /*Method=*/nullptr, ArrayRef(Args, NumArgs), RBracLoc,
2888 isImplicit);
2889 }
2890
2891 // If necessary, apply function/array conversion to the receiver.
2892 // C99 6.7.5.3p[7,8].
2893 ExprResult Result = DefaultFunctionArrayLvalueConversion(Receiver);
2894 if (Result.isInvalid())
2895 return ExprError();
2896 Receiver = Result.get();
2897 ReceiverType = Receiver->getType();
2898
2899 // If the receiver is an ObjC pointer, a block pointer, or an
2900 // __attribute__((NSObject)) pointer, we don't need to do any
2901 // special conversion in order to look up a receiver.
2902 if (ReceiverType->isObjCRetainableType()) {
2903 // do nothing
2904 } else if (!getLangOpts().ObjCAutoRefCount &&
2905 !Context.getObjCIdType().isNull() &&
2906 (ReceiverType->isPointerType() ||
2907 ReceiverType->isIntegerType())) {
2908 // Implicitly convert integers and pointers to 'id' but emit a warning.
2909 // But not in ARC.
2910 Diag(Loc, diag::warn_bad_receiver_type) << ReceiverType << RecRange;
2911 if (ReceiverType->isPointerType()) {
2912 Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(),
2913 CK_CPointerToObjCPointerCast).get();
2914 } else {
2915 // TODO: specialized warning on null receivers?
2916 bool IsNull = Receiver->isNullPointerConstant(Context,
2917 Expr::NPC_ValueDependentIsNull);
2918 CastKind Kind = IsNull ? CK_NullToPointer : CK_IntegralToPointer;
2919 Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(),
2920 Kind).get();
2921 }
2922 ReceiverType = Receiver->getType();
2923 } else if (getLangOpts().CPlusPlus) {
2924 // The receiver must be a complete type.
2925 if (RequireCompleteType(Loc, Receiver->getType(),
2926 diag::err_incomplete_receiver_type))
2927 return ExprError();
2928
2929 ExprResult result = PerformContextuallyConvertToObjCPointer(Receiver);
2930 if (result.isUsable()) {
2931 Receiver = result.get();
2932 ReceiverType = Receiver->getType();
2933 }
2934 }
2935 }
2936
2937 // There's a somewhat weird interaction here where we assume that we
2938 // won't actually have a method unless we also don't need to do some
2939 // of the more detailed type-checking on the receiver.
2940
2941 if (!Method) {
2942 // Handle messages to id and __kindof types (where we use the
2943 // global method pool).
2944 const ObjCObjectType *typeBound = nullptr;
2945 bool receiverIsIdLike = ReceiverType->isObjCIdOrObjectKindOfType(Context,
2946 typeBound);
2947 if (receiverIsIdLike || ReceiverType->isBlockPointerType() ||
2948 (Receiver && Context.isObjCNSObjectType(Receiver->getType()))) {
2949 SmallVector<ObjCMethodDecl*, 4> Methods;
2950 // If we have a type bound, further filter the methods.
2951 CollectMultipleMethodsInGlobalPool(Sel, Methods, true/*InstanceFirst*/,
2952 true/*CheckTheOther*/, typeBound);
2953 if (!Methods.empty()) {
2954 // We choose the first method as the initial candidate, then try to
2955 // select a better one.
2956 Method = Methods[0];
2957
2958 if (ObjCMethodDecl *BestMethod =
2959 SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(), Methods))
2960 Method = BestMethod;
2961
2962 if (!AreMultipleMethodsInGlobalPool(Sel, Method,
2963 SourceRange(LBracLoc, RBracLoc),
2964 receiverIsIdLike, Methods))
2965 DiagnoseUseOfDecl(Method, SelectorSlotLocs);
2966 }
2967 } else if (ReceiverType->isObjCClassOrClassKindOfType() ||
2968 ReceiverType->isObjCQualifiedClassType()) {
2969 // Handle messages to Class.
2970 // We allow sending a message to a qualified Class ("Class<foo>"), which
2971 // is ok as long as one of the protocols implements the selector (if not,
2972 // warn).
2973 if (!ReceiverType->isObjCClassOrClassKindOfType()) {
2974 const ObjCObjectPointerType *QClassTy
2975 = ReceiverType->getAsObjCQualifiedClassType();
2976 // Search protocols for class methods.
2977 Method = LookupMethodInQualifiedType(Sel, QClassTy, false);
2978 if (!Method) {
2979 Method = LookupMethodInQualifiedType(Sel, QClassTy, true);
2980 // warn if instance method found for a Class message.
2981 if (Method && !isMethodDeclaredInRootProtocol(*this, Method)) {
2982 Diag(SelLoc, diag::warn_instance_method_on_class_found)
2983 << Method->getSelector() << Sel;
2984 Diag(Method->getLocation(), diag::note_method_declared_at)
2985 << Method->getDeclName();
2986 }
2987 }
2988 } else {
2989 if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
2990 if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
2991 // As a guess, try looking for the method in the current interface.
2992 // This very well may not produce the "right" method.
2993
2994 // First check the public methods in the class interface.
2995 Method = ClassDecl->lookupClassMethod(Sel);
2996
2997 if (!Method)
2998 Method = ClassDecl->lookupPrivateClassMethod(Sel);
2999
3000 if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs))
3001 return ExprError();
3002 }
3003 }
3004 if (!Method) {
3005 // If not messaging 'self', look for any factory method named 'Sel'.
3006 if (!Receiver || !isSelfExpr(Receiver)) {
3007 // If no class (factory) method was found, check if an _instance_
3008 // method of the same name exists in the root class only.
3009 SmallVector<ObjCMethodDecl*, 4> Methods;
3010 CollectMultipleMethodsInGlobalPool(Sel, Methods,
3011 false/*InstanceFirst*/,
3012 true/*CheckTheOther*/);
3013 if (!Methods.empty()) {
3014 // We choose the first method as the initial candidate, then try
3015 // to select a better one.
3016 Method = Methods[0];
3017
3018 // If we find an instance method, emit warning.
3019 if (Method->isInstanceMethod()) {
3020 if (const ObjCInterfaceDecl *ID =
3021 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
3022 if (ID->getSuperClass())
3023 Diag(SelLoc, diag::warn_root_inst_method_not_found)
3024 << Sel << SourceRange(LBracLoc, RBracLoc);
3025 }
3026 }
3027
3028 if (ObjCMethodDecl *BestMethod =
3029 SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(),
3030 Methods))
3031 Method = BestMethod;
3032 }
3033 }
3034 }
3035 }
3036 } else {
3037 ObjCInterfaceDecl *ClassDecl = nullptr;
3038
3039 // We allow sending a message to a qualified ID ("id<foo>"), which is ok as
3040 // long as one of the protocols implements the selector (if not, warn).
3041 // And as long as message is not deprecated/unavailable (warn if it is).
3042 if (const ObjCObjectPointerType *QIdTy
3043 = ReceiverType->getAsObjCQualifiedIdType()) {
3044 // Search protocols for instance methods.
3045 Method = LookupMethodInQualifiedType(Sel, QIdTy, true);
3046 if (!Method)
3047 Method = LookupMethodInQualifiedType(Sel, QIdTy, false);
3048 if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs))
3049 return ExprError();
3050 } else if (const ObjCObjectPointerType *OCIType
3051 = ReceiverType->getAsObjCInterfacePointerType()) {
3052 // We allow sending a message to a pointer to an interface (an object).
3053 ClassDecl = OCIType->getInterfaceDecl();
3054
3055 // Try to complete the type. Under ARC, this is a hard error from which
3056 // we don't try to recover.
3057 // FIXME: In the non-ARC case, this will still be a hard error if the
3058 // definition is found in a module that's not visible.
3059 const ObjCInterfaceDecl *forwardClass = nullptr;
3060 if (RequireCompleteType(Loc, OCIType->getPointeeType(),
3061 getLangOpts().ObjCAutoRefCount
3062 ? diag::err_arc_receiver_forward_instance
3063 : diag::warn_receiver_forward_instance,
3064 RecRange)) {
3065 if (getLangOpts().ObjCAutoRefCount)
3066 return ExprError();
3067
3068 forwardClass = OCIType->getInterfaceDecl();
3069 Diag(Receiver ? Receiver->getBeginLoc() : SuperLoc,
3070 diag::note_receiver_is_id);
3071 Method = nullptr;
3072 } else {
3073 Method = ClassDecl->lookupInstanceMethod(Sel);
3074 }
3075
3076 if (!Method)
3077 // Search protocol qualifiers.
3078 Method = LookupMethodInQualifiedType(Sel, OCIType, true);
3079
3080 if (!Method) {
3081 // If we have implementations in scope, check "private" methods.
3082 Method = ClassDecl->lookupPrivateMethod(Sel);
3083
3084 if (!Method && getLangOpts().ObjCAutoRefCount) {
3085 Diag(SelLoc, diag::err_arc_may_not_respond)
3086 << OCIType->getPointeeType() << Sel << RecRange
3087 << SourceRange(SelectorLocs.front(), SelectorLocs.back());
3088 return ExprError();
3089 }
3090
3091 if (!Method && (!Receiver || !isSelfExpr(Receiver))) {
3092 // If we still haven't found a method, look in the global pool. This
3093 // behavior isn't very desirable, however we need it for GCC
3094 // compatibility. FIXME: should we deviate??
3095 if (OCIType->qual_empty()) {
3096 SmallVector<ObjCMethodDecl*, 4> Methods;
3097 CollectMultipleMethodsInGlobalPool(Sel, Methods,
3098 true/*InstanceFirst*/,
3099 false/*CheckTheOther*/);
3100 if (!Methods.empty()) {
3101 // We choose the first method as the initial candidate, then try
3102 // to select a better one.
3103 Method = Methods[0];
3104
3105 if (ObjCMethodDecl *BestMethod =
3106 SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(),
3107 Methods))
3108 Method = BestMethod;
3109
3110 AreMultipleMethodsInGlobalPool(Sel, Method,
3111 SourceRange(LBracLoc, RBracLoc),
3112 true/*receiverIdOrClass*/,
3113 Methods);
3114 }
3115 if (Method && !forwardClass)
3116 Diag(SelLoc, diag::warn_maynot_respond)
3117 << OCIType->getInterfaceDecl()->getIdentifier()
3118 << Sel << RecRange;
3119 }
3120 }
3121 }
3122 if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs, forwardClass))
3123 return ExprError();
3124 } else {
3125 // Reject other random receiver types (e.g. structs).
3126 Diag(Loc, diag::err_bad_receiver_type) << ReceiverType << RecRange;
3127 return ExprError();
3128 }
3129 }
3130 }
3131
3132 FunctionScopeInfo *DIFunctionScopeInfo =
3133 (Method && Method->getMethodFamily() == OMF_init)
3134 ? getEnclosingFunction() : nullptr;
3135
3136 if (Method && Method->isDirectMethod()) {
3137 if (ReceiverType->isObjCIdType() && !isImplicit) {
3138 Diag(Receiver->getExprLoc(),
3139 diag::err_messaging_unqualified_id_with_direct_method);
3140 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
3141 << Method->getDeclName();
3142 }
3143
3144 // Under ARC, self can't be assigned, and doing a direct call to `self`
3145 // when it's a Class is hence safe. For other cases, we can't trust `self`
3146 // is what we think it is, so we reject it.
3147 if (ReceiverType->isObjCClassType() && !isImplicit &&
3148 !(Receiver->isObjCSelfExpr() && getLangOpts().ObjCAutoRefCount)) {
3149 {
3150 auto Builder = Diag(Receiver->getExprLoc(),
3151 diag::err_messaging_class_with_direct_method);
3152 if (Receiver->isObjCSelfExpr()) {
3153 Builder.AddFixItHint(FixItHint::CreateReplacement(
3154 RecRange, Method->getClassInterface()->getName()));
3155 }
3156 }
3157 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
3158 << Method->getDeclName();
3159 }
3160
3161 if (SuperLoc.isValid()) {
3162 {
3163 auto Builder =
3164 Diag(SuperLoc, diag::err_messaging_super_with_direct_method);
3165 if (ReceiverType->isObjCClassType()) {
3166 Builder.AddFixItHint(FixItHint::CreateReplacement(
3167 SuperLoc, Method->getClassInterface()->getName()));
3168 } else {
3169 Builder.AddFixItHint(FixItHint::CreateReplacement(SuperLoc, "self"));
3170 }
3171 }
3172 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
3173 << Method->getDeclName();
3174 }
3175 } else if (ReceiverType->isObjCIdType() && !isImplicit) {
3176 Diag(Receiver->getExprLoc(), diag::warn_messaging_unqualified_id);
3177 }
3178
3179 if (DIFunctionScopeInfo &&
3180 DIFunctionScopeInfo->ObjCIsDesignatedInit &&
3181 (SuperLoc.isValid() || isSelfExpr(Receiver))) {
3182 bool isDesignatedInitChain = false;
3183 if (SuperLoc.isValid()) {
3184 if (const ObjCObjectPointerType *
3185 OCIType = ReceiverType->getAsObjCInterfacePointerType()) {
3186 if (const ObjCInterfaceDecl *ID = OCIType->getInterfaceDecl()) {
3187 // Either we know this is a designated initializer or we
3188 // conservatively assume it because we don't know for sure.
3189 if (!ID->declaresOrInheritsDesignatedInitializers() ||
3190 ID->isDesignatedInitializer(Sel)) {
3191 isDesignatedInitChain = true;
3192 DIFunctionScopeInfo->ObjCWarnForNoDesignatedInitChain = false;
3193 }
3194 }
3195 }
3196 }
3197 if (!isDesignatedInitChain) {
3198 const ObjCMethodDecl *InitMethod = nullptr;
3199 bool isDesignated =
3200 getCurMethodDecl()->isDesignatedInitializerForTheInterface(&InitMethod);
3201 assert(isDesignated && InitMethod);
3202 (void)isDesignated;
3203 Diag(SelLoc, SuperLoc.isValid() ?
3204 diag::warn_objc_designated_init_non_designated_init_call :
3205 diag::warn_objc_designated_init_non_super_designated_init_call);
3206 Diag(InitMethod->getLocation(),
3207 diag::note_objc_designated_init_marked_here);
3208 }
3209 }
3210
3211 if (DIFunctionScopeInfo &&
3212 DIFunctionScopeInfo->ObjCIsSecondaryInit &&
3213 (SuperLoc.isValid() || isSelfExpr(Receiver))) {
3214 if (SuperLoc.isValid()) {
3215 Diag(SelLoc, diag::warn_objc_secondary_init_super_init_call);
3216 } else {
3217 DIFunctionScopeInfo->ObjCWarnForNoInitDelegation = false;
3218 }
3219 }
3220
3221 // Check the message arguments.
3222 unsigned NumArgs = ArgsIn.size();
3223 Expr **Args = ArgsIn.data();
3224 QualType ReturnType;
3225 ExprValueKind VK = VK_PRValue;
3226 bool ClassMessage = (ReceiverType->isObjCClassType() ||
3227 ReceiverType->isObjCQualifiedClassType());
3228 if (CheckMessageArgumentTypes(Receiver, ReceiverType,
3229 MultiExprArg(Args, NumArgs), Sel, SelectorLocs,
3230 Method, ClassMessage, SuperLoc.isValid(),
3231 LBracLoc, RBracLoc, RecRange, ReturnType, VK))
3232 return ExprError();
3233
3234 if (Method && !Method->getReturnType()->isVoidType() &&
3235 RequireCompleteType(LBracLoc, Method->getReturnType(),
3236 diag::err_illegal_message_expr_incomplete_type))
3237 return ExprError();
3238
3239 // In ARC, forbid the user from sending messages to
3240 // retain/release/autorelease/dealloc/retainCount explicitly.
3241 if (getLangOpts().ObjCAutoRefCount) {
3242 ObjCMethodFamily family =
3243 (Method ? Method->getMethodFamily() : Sel.getMethodFamily());
3244 switch (family) {
3245 case OMF_init:
3246 if (Method)
3247 checkInitMethod(Method, ReceiverType);
3248 break;
3249
3250 case OMF_None:
3251 case OMF_alloc:
3252 case OMF_copy:
3253 case OMF_finalize:
3254 case OMF_mutableCopy:
3255 case OMF_new:
3256 case OMF_self:
3257 case OMF_initialize:
3258 break;
3259
3260 case OMF_dealloc:
3261 case OMF_retain:
3262 case OMF_release:
3263 case OMF_autorelease:
3264 case OMF_retainCount:
3265 Diag(SelLoc, diag::err_arc_illegal_explicit_message)
3266 << Sel << RecRange;
3267 break;
3268
3269 case OMF_performSelector:
3270 if (Method && NumArgs >= 1) {
3271 if (const auto *SelExp =
3272 dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens())) {
3273 Selector ArgSel = SelExp->getSelector();
3274 ObjCMethodDecl *SelMethod =
3275 LookupInstanceMethodInGlobalPool(ArgSel,
3276 SelExp->getSourceRange());
3277 if (!SelMethod)
3278 SelMethod =
3279 LookupFactoryMethodInGlobalPool(ArgSel,
3280 SelExp->getSourceRange());
3281 if (SelMethod) {
3282 ObjCMethodFamily SelFamily = SelMethod->getMethodFamily();
3283 switch (SelFamily) {
3284 case OMF_alloc:
3285 case OMF_copy:
3286 case OMF_mutableCopy:
3287 case OMF_new:
3288 case OMF_init:
3289 // Issue error, unless ns_returns_not_retained.
3290 if (!SelMethod->hasAttr<NSReturnsNotRetainedAttr>()) {
3291 // selector names a +1 method
3292 Diag(SelLoc,
3293 diag::err_arc_perform_selector_retains);
3294 Diag(SelMethod->getLocation(), diag::note_method_declared_at)
3295 << SelMethod->getDeclName();
3296 }
3297 break;
3298 default:
3299 // +0 call. OK. unless ns_returns_retained.
3300 if (SelMethod->hasAttr<NSReturnsRetainedAttr>()) {
3301 // selector names a +1 method
3302 Diag(SelLoc,
3303 diag::err_arc_perform_selector_retains);
3304 Diag(SelMethod->getLocation(), diag::note_method_declared_at)
3305 << SelMethod->getDeclName();
3306 }
3307 break;
3308 }
3309 }
3310 } else {
3311 // error (may leak).
3312 Diag(SelLoc, diag::warn_arc_perform_selector_leaks);
3313 Diag(Args[0]->getExprLoc(), diag::note_used_here);
3314 }
3315 }
3316 break;
3317 }
3318 }
3319
3320 DiagnoseCStringFormatDirectiveInObjCAPI(*this, Method, Sel, Args, NumArgs);
3321
3322 // Construct the appropriate ObjCMessageExpr instance.
3323 ObjCMessageExpr *Result;
3324 if (SuperLoc.isValid())
3325 Result = ObjCMessageExpr::Create(
3326 Context, ReturnType, VK, LBracLoc, SuperLoc, /*IsInstanceSuper=*/true,
3327 ReceiverType, Sel, SelectorLocs, Method, ArrayRef(Args, NumArgs),
3328 RBracLoc, isImplicit);
3329 else {
3330 Result = ObjCMessageExpr::Create(
3331 Context, ReturnType, VK, LBracLoc, Receiver, Sel, SelectorLocs, Method,
3332 ArrayRef(Args, NumArgs), RBracLoc, isImplicit);
3333 if (!isImplicit)
3334 checkCocoaAPI(*this, Result);
3335 }
3336 if (Method) {
3337 bool IsClassObjectCall = ClassMessage;
3338 // 'self' message receivers in class methods should be treated as message
3339 // sends to the class object in order for the semantic checks to be
3340 // performed correctly. Messages to 'super' already count as class messages,
3341 // so they don't need to be handled here.
3342 if (Receiver && isSelfExpr(Receiver)) {
3343 if (const auto *OPT = ReceiverType->getAs<ObjCObjectPointerType>()) {
3344 if (OPT->getObjectType()->isObjCClass()) {
3345 if (const auto *CurMeth = getCurMethodDecl()) {
3346 IsClassObjectCall = true;
3347 ReceiverType =
3348 Context.getObjCInterfaceType(CurMeth->getClassInterface());
3349 }
3350 }
3351 }
3352 }
3353 checkFoundationAPI(*this, SelLoc, Method, ArrayRef(Args, NumArgs),
3354 ReceiverType, IsClassObjectCall);
3355 }
3356
3357 if (getLangOpts().ObjCAutoRefCount) {
3358 // In ARC, annotate delegate init calls.
3359 if (Result->getMethodFamily() == OMF_init &&
3360 (SuperLoc.isValid() || isSelfExpr(Receiver))) {
3361 // Only consider init calls *directly* in init implementations,
3362 // not within blocks.
3363 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(CurContext);
3364 if (method && method->getMethodFamily() == OMF_init) {
3365 // The implicit assignment to self means we also don't want to
3366 // consume the result.
3367 Result->setDelegateInitCall(true);
3368 return Result;
3369 }
3370 }
3371
3372 // In ARC, check for message sends which are likely to introduce
3373 // retain cycles.
3374 checkRetainCycles(Result);
3375 }
3376
3377 if (getLangOpts().ObjCWeak) {
3378 if (!isImplicit && Method) {
3379 if (const ObjCPropertyDecl *Prop = Method->findPropertyDecl()) {
3380 bool IsWeak =
3381 Prop->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak;
3382 if (!IsWeak && Sel.isUnarySelector())
3383 IsWeak = ReturnType.getObjCLifetime() & Qualifiers::OCL_Weak;
3384 if (IsWeak && !isUnevaluatedContext() &&
3385 !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, LBracLoc))
3386 getCurFunction()->recordUseOfWeak(Result, Prop);
3387 }
3388 }
3389 }
3390
3391 CheckObjCCircularContainer(Result);
3392
3393 return MaybeBindToTemporary(Result);
3394 }
3395
RemoveSelectorFromWarningCache(Sema & S,Expr * Arg)3396 static void RemoveSelectorFromWarningCache(Sema &S, Expr* Arg) {
3397 if (ObjCSelectorExpr *OSE =
3398 dyn_cast<ObjCSelectorExpr>(Arg->IgnoreParenCasts())) {
3399 Selector Sel = OSE->getSelector();
3400 SourceLocation Loc = OSE->getAtLoc();
3401 auto Pos = S.ReferencedSelectors.find(Sel);
3402 if (Pos != S.ReferencedSelectors.end() && Pos->second == Loc)
3403 S.ReferencedSelectors.erase(Pos);
3404 }
3405 }
3406
3407 // ActOnInstanceMessage - used for both unary and keyword messages.
3408 // ArgExprs is optional - if it is present, the number of expressions
3409 // is obtained from Sel.getNumArgs().
ActOnInstanceMessage(Scope * S,Expr * Receiver,Selector Sel,SourceLocation LBracLoc,ArrayRef<SourceLocation> SelectorLocs,SourceLocation RBracLoc,MultiExprArg Args)3410 ExprResult Sema::ActOnInstanceMessage(Scope *S,
3411 Expr *Receiver,
3412 Selector Sel,
3413 SourceLocation LBracLoc,
3414 ArrayRef<SourceLocation> SelectorLocs,
3415 SourceLocation RBracLoc,
3416 MultiExprArg Args) {
3417 if (!Receiver)
3418 return ExprError();
3419
3420 // A ParenListExpr can show up while doing error recovery with invalid code.
3421 if (isa<ParenListExpr>(Receiver)) {
3422 ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Receiver);
3423 if (Result.isInvalid()) return ExprError();
3424 Receiver = Result.get();
3425 }
3426
3427 if (RespondsToSelectorSel.isNull()) {
3428 IdentifierInfo *SelectorId = &Context.Idents.get("respondsToSelector");
3429 RespondsToSelectorSel = Context.Selectors.getUnarySelector(SelectorId);
3430 }
3431 if (Sel == RespondsToSelectorSel)
3432 RemoveSelectorFromWarningCache(*this, Args[0]);
3433
3434 return BuildInstanceMessage(Receiver, Receiver->getType(),
3435 /*SuperLoc=*/SourceLocation(), Sel,
3436 /*Method=*/nullptr, LBracLoc, SelectorLocs,
3437 RBracLoc, Args);
3438 }
3439
3440 enum ARCConversionTypeClass {
3441 /// int, void, struct A
3442 ACTC_none,
3443
3444 /// id, void (^)()
3445 ACTC_retainable,
3446
3447 /// id*, id***, void (^*)(),
3448 ACTC_indirectRetainable,
3449
3450 /// void* might be a normal C type, or it might a CF type.
3451 ACTC_voidPtr,
3452
3453 /// struct A*
3454 ACTC_coreFoundation
3455 };
3456
isAnyRetainable(ARCConversionTypeClass ACTC)3457 static bool isAnyRetainable(ARCConversionTypeClass ACTC) {
3458 return (ACTC == ACTC_retainable ||
3459 ACTC == ACTC_coreFoundation ||
3460 ACTC == ACTC_voidPtr);
3461 }
3462
isAnyCLike(ARCConversionTypeClass ACTC)3463 static bool isAnyCLike(ARCConversionTypeClass ACTC) {
3464 return ACTC == ACTC_none ||
3465 ACTC == ACTC_voidPtr ||
3466 ACTC == ACTC_coreFoundation;
3467 }
3468
classifyTypeForARCConversion(QualType type)3469 static ARCConversionTypeClass classifyTypeForARCConversion(QualType type) {
3470 bool isIndirect = false;
3471
3472 // Ignore an outermost reference type.
3473 if (const ReferenceType *ref = type->getAs<ReferenceType>()) {
3474 type = ref->getPointeeType();
3475 isIndirect = true;
3476 }
3477
3478 // Drill through pointers and arrays recursively.
3479 while (true) {
3480 if (const PointerType *ptr = type->getAs<PointerType>()) {
3481 type = ptr->getPointeeType();
3482
3483 // The first level of pointer may be the innermost pointer on a CF type.
3484 if (!isIndirect) {
3485 if (type->isVoidType()) return ACTC_voidPtr;
3486 if (type->isRecordType()) return ACTC_coreFoundation;
3487 }
3488 } else if (const ArrayType *array = type->getAsArrayTypeUnsafe()) {
3489 type = QualType(array->getElementType()->getBaseElementTypeUnsafe(), 0);
3490 } else {
3491 break;
3492 }
3493 isIndirect = true;
3494 }
3495
3496 if (isIndirect) {
3497 if (type->isObjCARCBridgableType())
3498 return ACTC_indirectRetainable;
3499 return ACTC_none;
3500 }
3501
3502 if (type->isObjCARCBridgableType())
3503 return ACTC_retainable;
3504
3505 return ACTC_none;
3506 }
3507
3508 namespace {
3509 /// A result from the cast checker.
3510 enum ACCResult {
3511 /// Cannot be casted.
3512 ACC_invalid,
3513
3514 /// Can be safely retained or not retained.
3515 ACC_bottom,
3516
3517 /// Can be casted at +0.
3518 ACC_plusZero,
3519
3520 /// Can be casted at +1.
3521 ACC_plusOne
3522 };
merge(ACCResult left,ACCResult right)3523 ACCResult merge(ACCResult left, ACCResult right) {
3524 if (left == right) return left;
3525 if (left == ACC_bottom) return right;
3526 if (right == ACC_bottom) return left;
3527 return ACC_invalid;
3528 }
3529
3530 /// A checker which white-lists certain expressions whose conversion
3531 /// to or from retainable type would otherwise be forbidden in ARC.
3532 class ARCCastChecker : public StmtVisitor<ARCCastChecker, ACCResult> {
3533 typedef StmtVisitor<ARCCastChecker, ACCResult> super;
3534
3535 ASTContext &Context;
3536 ARCConversionTypeClass SourceClass;
3537 ARCConversionTypeClass TargetClass;
3538 bool Diagnose;
3539
isCFType(QualType type)3540 static bool isCFType(QualType type) {
3541 // Someday this can use ns_bridged. For now, it has to do this.
3542 return type->isCARCBridgableType();
3543 }
3544
3545 public:
ARCCastChecker(ASTContext & Context,ARCConversionTypeClass source,ARCConversionTypeClass target,bool diagnose)3546 ARCCastChecker(ASTContext &Context, ARCConversionTypeClass source,
3547 ARCConversionTypeClass target, bool diagnose)
3548 : Context(Context), SourceClass(source), TargetClass(target),
3549 Diagnose(diagnose) {}
3550
3551 using super::Visit;
Visit(Expr * e)3552 ACCResult Visit(Expr *e) {
3553 return super::Visit(e->IgnoreParens());
3554 }
3555
VisitStmt(Stmt * s)3556 ACCResult VisitStmt(Stmt *s) {
3557 return ACC_invalid;
3558 }
3559
3560 /// Null pointer constants can be casted however you please.
VisitExpr(Expr * e)3561 ACCResult VisitExpr(Expr *e) {
3562 if (e->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull))
3563 return ACC_bottom;
3564 return ACC_invalid;
3565 }
3566
3567 /// Objective-C string literals can be safely casted.
VisitObjCStringLiteral(ObjCStringLiteral * e)3568 ACCResult VisitObjCStringLiteral(ObjCStringLiteral *e) {
3569 // If we're casting to any retainable type, go ahead. Global
3570 // strings are immune to retains, so this is bottom.
3571 if (isAnyRetainable(TargetClass)) return ACC_bottom;
3572
3573 return ACC_invalid;
3574 }
3575
3576 /// Look through certain implicit and explicit casts.
VisitCastExpr(CastExpr * e)3577 ACCResult VisitCastExpr(CastExpr *e) {
3578 switch (e->getCastKind()) {
3579 case CK_NullToPointer:
3580 return ACC_bottom;
3581
3582 case CK_NoOp:
3583 case CK_LValueToRValue:
3584 case CK_BitCast:
3585 case CK_CPointerToObjCPointerCast:
3586 case CK_BlockPointerToObjCPointerCast:
3587 case CK_AnyPointerToBlockPointerCast:
3588 return Visit(e->getSubExpr());
3589
3590 default:
3591 return ACC_invalid;
3592 }
3593 }
3594
3595 /// Look through unary extension.
VisitUnaryExtension(UnaryOperator * e)3596 ACCResult VisitUnaryExtension(UnaryOperator *e) {
3597 return Visit(e->getSubExpr());
3598 }
3599
3600 /// Ignore the LHS of a comma operator.
VisitBinComma(BinaryOperator * e)3601 ACCResult VisitBinComma(BinaryOperator *e) {
3602 return Visit(e->getRHS());
3603 }
3604
3605 /// Conditional operators are okay if both sides are okay.
VisitConditionalOperator(ConditionalOperator * e)3606 ACCResult VisitConditionalOperator(ConditionalOperator *e) {
3607 ACCResult left = Visit(e->getTrueExpr());
3608 if (left == ACC_invalid) return ACC_invalid;
3609 return merge(left, Visit(e->getFalseExpr()));
3610 }
3611
3612 /// Look through pseudo-objects.
VisitPseudoObjectExpr(PseudoObjectExpr * e)3613 ACCResult VisitPseudoObjectExpr(PseudoObjectExpr *e) {
3614 // If we're getting here, we should always have a result.
3615 return Visit(e->getResultExpr());
3616 }
3617
3618 /// Statement expressions are okay if their result expression is okay.
VisitStmtExpr(StmtExpr * e)3619 ACCResult VisitStmtExpr(StmtExpr *e) {
3620 return Visit(e->getSubStmt()->body_back());
3621 }
3622
3623 /// Some declaration references are okay.
VisitDeclRefExpr(DeclRefExpr * e)3624 ACCResult VisitDeclRefExpr(DeclRefExpr *e) {
3625 VarDecl *var = dyn_cast<VarDecl>(e->getDecl());
3626 // References to global constants are okay.
3627 if (isAnyRetainable(TargetClass) &&
3628 isAnyRetainable(SourceClass) &&
3629 var &&
3630 !var->hasDefinition(Context) &&
3631 var->getType().isConstQualified()) {
3632
3633 // In system headers, they can also be assumed to be immune to retains.
3634 // These are things like 'kCFStringTransformToLatin'.
3635 if (Context.getSourceManager().isInSystemHeader(var->getLocation()))
3636 return ACC_bottom;
3637
3638 return ACC_plusZero;
3639 }
3640
3641 // Nothing else.
3642 return ACC_invalid;
3643 }
3644
3645 /// Some calls are okay.
VisitCallExpr(CallExpr * e)3646 ACCResult VisitCallExpr(CallExpr *e) {
3647 if (FunctionDecl *fn = e->getDirectCallee())
3648 if (ACCResult result = checkCallToFunction(fn))
3649 return result;
3650
3651 return super::VisitCallExpr(e);
3652 }
3653
checkCallToFunction(FunctionDecl * fn)3654 ACCResult checkCallToFunction(FunctionDecl *fn) {
3655 // Require a CF*Ref return type.
3656 if (!isCFType(fn->getReturnType()))
3657 return ACC_invalid;
3658
3659 if (!isAnyRetainable(TargetClass))
3660 return ACC_invalid;
3661
3662 // Honor an explicit 'not retained' attribute.
3663 if (fn->hasAttr<CFReturnsNotRetainedAttr>())
3664 return ACC_plusZero;
3665
3666 // Honor an explicit 'retained' attribute, except that for
3667 // now we're not going to permit implicit handling of +1 results,
3668 // because it's a bit frightening.
3669 if (fn->hasAttr<CFReturnsRetainedAttr>())
3670 return Diagnose ? ACC_plusOne
3671 : ACC_invalid; // ACC_plusOne if we start accepting this
3672
3673 // Recognize this specific builtin function, which is used by CFSTR.
3674 unsigned builtinID = fn->getBuiltinID();
3675 if (builtinID == Builtin::BI__builtin___CFStringMakeConstantString)
3676 return ACC_bottom;
3677
3678 // Otherwise, don't do anything implicit with an unaudited function.
3679 if (!fn->hasAttr<CFAuditedTransferAttr>())
3680 return ACC_invalid;
3681
3682 // Otherwise, it's +0 unless it follows the create convention.
3683 if (ento::coreFoundation::followsCreateRule(fn))
3684 return Diagnose ? ACC_plusOne
3685 : ACC_invalid; // ACC_plusOne if we start accepting this
3686
3687 return ACC_plusZero;
3688 }
3689
VisitObjCMessageExpr(ObjCMessageExpr * e)3690 ACCResult VisitObjCMessageExpr(ObjCMessageExpr *e) {
3691 return checkCallToMethod(e->getMethodDecl());
3692 }
3693
VisitObjCPropertyRefExpr(ObjCPropertyRefExpr * e)3694 ACCResult VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *e) {
3695 ObjCMethodDecl *method;
3696 if (e->isExplicitProperty())
3697 method = e->getExplicitProperty()->getGetterMethodDecl();
3698 else
3699 method = e->getImplicitPropertyGetter();
3700 return checkCallToMethod(method);
3701 }
3702
checkCallToMethod(ObjCMethodDecl * method)3703 ACCResult checkCallToMethod(ObjCMethodDecl *method) {
3704 if (!method) return ACC_invalid;
3705
3706 // Check for message sends to functions returning CF types. We
3707 // just obey the Cocoa conventions with these, even though the
3708 // return type is CF.
3709 if (!isAnyRetainable(TargetClass) || !isCFType(method->getReturnType()))
3710 return ACC_invalid;
3711
3712 // If the method is explicitly marked not-retained, it's +0.
3713 if (method->hasAttr<CFReturnsNotRetainedAttr>())
3714 return ACC_plusZero;
3715
3716 // If the method is explicitly marked as returning retained, or its
3717 // selector follows a +1 Cocoa convention, treat it as +1.
3718 if (method->hasAttr<CFReturnsRetainedAttr>())
3719 return ACC_plusOne;
3720
3721 switch (method->getSelector().getMethodFamily()) {
3722 case OMF_alloc:
3723 case OMF_copy:
3724 case OMF_mutableCopy:
3725 case OMF_new:
3726 return ACC_plusOne;
3727
3728 default:
3729 // Otherwise, treat it as +0.
3730 return ACC_plusZero;
3731 }
3732 }
3733 };
3734 } // end anonymous namespace
3735
isKnownName(StringRef name)3736 bool Sema::isKnownName(StringRef name) {
3737 if (name.empty())
3738 return false;
3739 LookupResult R(*this, &Context.Idents.get(name), SourceLocation(),
3740 Sema::LookupOrdinaryName);
3741 return LookupName(R, TUScope, false);
3742 }
3743
3744 template <typename DiagBuilderT>
addFixitForObjCARCConversion(Sema & S,DiagBuilderT & DiagB,Sema::CheckedConversionKind CCK,SourceLocation afterLParen,QualType castType,Expr * castExpr,Expr * realCast,const char * bridgeKeyword,const char * CFBridgeName)3745 static void addFixitForObjCARCConversion(
3746 Sema &S, DiagBuilderT &DiagB, Sema::CheckedConversionKind CCK,
3747 SourceLocation afterLParen, QualType castType, Expr *castExpr,
3748 Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName) {
3749 // We handle C-style and implicit casts here.
3750 switch (CCK) {
3751 case Sema::CCK_ImplicitConversion:
3752 case Sema::CCK_ForBuiltinOverloadedOp:
3753 case Sema::CCK_CStyleCast:
3754 case Sema::CCK_OtherCast:
3755 break;
3756 case Sema::CCK_FunctionalCast:
3757 return;
3758 }
3759
3760 if (CFBridgeName) {
3761 if (CCK == Sema::CCK_OtherCast) {
3762 if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) {
3763 SourceRange range(NCE->getOperatorLoc(),
3764 NCE->getAngleBrackets().getEnd());
3765 SmallString<32> BridgeCall;
3766
3767 SourceManager &SM = S.getSourceManager();
3768 char PrevChar = *SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
3769 if (Lexer::isAsciiIdentifierContinueChar(PrevChar, S.getLangOpts()))
3770 BridgeCall += ' ';
3771
3772 BridgeCall += CFBridgeName;
3773 DiagB.AddFixItHint(FixItHint::CreateReplacement(range, BridgeCall));
3774 }
3775 return;
3776 }
3777 Expr *castedE = castExpr;
3778 if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(castedE))
3779 castedE = CCE->getSubExpr();
3780 castedE = castedE->IgnoreImpCasts();
3781 SourceRange range = castedE->getSourceRange();
3782
3783 SmallString<32> BridgeCall;
3784
3785 SourceManager &SM = S.getSourceManager();
3786 char PrevChar = *SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
3787 if (Lexer::isAsciiIdentifierContinueChar(PrevChar, S.getLangOpts()))
3788 BridgeCall += ' ';
3789
3790 BridgeCall += CFBridgeName;
3791
3792 if (isa<ParenExpr>(castedE)) {
3793 DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
3794 BridgeCall));
3795 } else {
3796 BridgeCall += '(';
3797 DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
3798 BridgeCall));
3799 DiagB.AddFixItHint(FixItHint::CreateInsertion(
3800 S.getLocForEndOfToken(range.getEnd()),
3801 ")"));
3802 }
3803 return;
3804 }
3805
3806 if (CCK == Sema::CCK_CStyleCast) {
3807 DiagB.AddFixItHint(FixItHint::CreateInsertion(afterLParen, bridgeKeyword));
3808 } else if (CCK == Sema::CCK_OtherCast) {
3809 if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) {
3810 std::string castCode = "(";
3811 castCode += bridgeKeyword;
3812 castCode += castType.getAsString();
3813 castCode += ")";
3814 SourceRange Range(NCE->getOperatorLoc(),
3815 NCE->getAngleBrackets().getEnd());
3816 DiagB.AddFixItHint(FixItHint::CreateReplacement(Range, castCode));
3817 }
3818 } else {
3819 std::string castCode = "(";
3820 castCode += bridgeKeyword;
3821 castCode += castType.getAsString();
3822 castCode += ")";
3823 Expr *castedE = castExpr->IgnoreImpCasts();
3824 SourceRange range = castedE->getSourceRange();
3825 if (isa<ParenExpr>(castedE)) {
3826 DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
3827 castCode));
3828 } else {
3829 castCode += "(";
3830 DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
3831 castCode));
3832 DiagB.AddFixItHint(FixItHint::CreateInsertion(
3833 S.getLocForEndOfToken(range.getEnd()),
3834 ")"));
3835 }
3836 }
3837 }
3838
3839 template <typename T>
getObjCBridgeAttr(const TypedefType * TD)3840 static inline T *getObjCBridgeAttr(const TypedefType *TD) {
3841 TypedefNameDecl *TDNDecl = TD->getDecl();
3842 QualType QT = TDNDecl->getUnderlyingType();
3843 if (QT->isPointerType()) {
3844 QT = QT->getPointeeType();
3845 if (const RecordType *RT = QT->getAs<RecordType>()) {
3846 for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {
3847 if (auto *attr = Redecl->getAttr<T>())
3848 return attr;
3849 }
3850 }
3851 }
3852 return nullptr;
3853 }
3854
ObjCBridgeRelatedAttrFromType(QualType T,TypedefNameDecl * & TDNDecl)3855 static ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttrFromType(QualType T,
3856 TypedefNameDecl *&TDNDecl) {
3857 while (const auto *TD = T->getAs<TypedefType>()) {
3858 TDNDecl = TD->getDecl();
3859 if (ObjCBridgeRelatedAttr *ObjCBAttr =
3860 getObjCBridgeAttr<ObjCBridgeRelatedAttr>(TD))
3861 return ObjCBAttr;
3862 T = TDNDecl->getUnderlyingType();
3863 }
3864 return nullptr;
3865 }
3866
3867 static void
diagnoseObjCARCConversion(Sema & S,SourceRange castRange,QualType castType,ARCConversionTypeClass castACTC,Expr * castExpr,Expr * realCast,ARCConversionTypeClass exprACTC,Sema::CheckedConversionKind CCK)3868 diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
3869 QualType castType, ARCConversionTypeClass castACTC,
3870 Expr *castExpr, Expr *realCast,
3871 ARCConversionTypeClass exprACTC,
3872 Sema::CheckedConversionKind CCK) {
3873 SourceLocation loc =
3874 (castRange.isValid() ? castRange.getBegin() : castExpr->getExprLoc());
3875
3876 if (S.makeUnavailableInSystemHeader(loc,
3877 UnavailableAttr::IR_ARCForbiddenConversion))
3878 return;
3879
3880 QualType castExprType = castExpr->getType();
3881 // Defer emitting a diagnostic for bridge-related casts; that will be
3882 // handled by CheckObjCBridgeRelatedConversions.
3883 TypedefNameDecl *TDNDecl = nullptr;
3884 if ((castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable &&
3885 ObjCBridgeRelatedAttrFromType(castType, TDNDecl)) ||
3886 (exprACTC == ACTC_coreFoundation && castACTC == ACTC_retainable &&
3887 ObjCBridgeRelatedAttrFromType(castExprType, TDNDecl)))
3888 return;
3889
3890 unsigned srcKind = 0;
3891 switch (exprACTC) {
3892 case ACTC_none:
3893 case ACTC_coreFoundation:
3894 case ACTC_voidPtr:
3895 srcKind = (castExprType->isPointerType() ? 1 : 0);
3896 break;
3897 case ACTC_retainable:
3898 srcKind = (castExprType->isBlockPointerType() ? 2 : 3);
3899 break;
3900 case ACTC_indirectRetainable:
3901 srcKind = 4;
3902 break;
3903 }
3904
3905 // Check whether this could be fixed with a bridge cast.
3906 SourceLocation afterLParen = S.getLocForEndOfToken(castRange.getBegin());
3907 SourceLocation noteLoc = afterLParen.isValid() ? afterLParen : loc;
3908
3909 unsigned convKindForDiag = Sema::isCast(CCK) ? 0 : 1;
3910
3911 // Bridge from an ARC type to a CF type.
3912 if (castACTC == ACTC_retainable && isAnyRetainable(exprACTC)) {
3913
3914 S.Diag(loc, diag::err_arc_cast_requires_bridge)
3915 << convKindForDiag
3916 << 2 // of C pointer type
3917 << castExprType
3918 << unsigned(castType->isBlockPointerType()) // to ObjC|block type
3919 << castType
3920 << castRange
3921 << castExpr->getSourceRange();
3922 bool br = S.isKnownName("CFBridgingRelease");
3923 ACCResult CreateRule =
3924 ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr);
3925 assert(CreateRule != ACC_bottom && "This cast should already be accepted.");
3926 if (CreateRule != ACC_plusOne)
3927 {
3928 auto DiagB = (CCK != Sema::CCK_OtherCast)
3929 ? S.Diag(noteLoc, diag::note_arc_bridge)
3930 : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);
3931
3932 addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
3933 castType, castExpr, realCast, "__bridge ",
3934 nullptr);
3935 }
3936 if (CreateRule != ACC_plusZero)
3937 {
3938 auto DiagB = (CCK == Sema::CCK_OtherCast && !br)
3939 ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_transfer)
3940 << castExprType
3941 : S.Diag(br ? castExpr->getExprLoc() : noteLoc,
3942 diag::note_arc_bridge_transfer)
3943 << castExprType << br;
3944
3945 addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
3946 castType, castExpr, realCast, "__bridge_transfer ",
3947 br ? "CFBridgingRelease" : nullptr);
3948 }
3949
3950 return;
3951 }
3952
3953 // Bridge from a CF type to an ARC type.
3954 if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC)) {
3955 bool br = S.isKnownName("CFBridgingRetain");
3956 S.Diag(loc, diag::err_arc_cast_requires_bridge)
3957 << convKindForDiag
3958 << unsigned(castExprType->isBlockPointerType()) // of ObjC|block type
3959 << castExprType
3960 << 2 // to C pointer type
3961 << castType
3962 << castRange
3963 << castExpr->getSourceRange();
3964 ACCResult CreateRule =
3965 ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr);
3966 assert(CreateRule != ACC_bottom && "This cast should already be accepted.");
3967 if (CreateRule != ACC_plusOne)
3968 {
3969 auto DiagB = (CCK != Sema::CCK_OtherCast)
3970 ? S.Diag(noteLoc, diag::note_arc_bridge)
3971 : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);
3972 addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
3973 castType, castExpr, realCast, "__bridge ",
3974 nullptr);
3975 }
3976 if (CreateRule != ACC_plusZero)
3977 {
3978 auto DiagB = (CCK == Sema::CCK_OtherCast && !br)
3979 ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_retained)
3980 << castType
3981 : S.Diag(br ? castExpr->getExprLoc() : noteLoc,
3982 diag::note_arc_bridge_retained)
3983 << castType << br;
3984
3985 addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
3986 castType, castExpr, realCast, "__bridge_retained ",
3987 br ? "CFBridgingRetain" : nullptr);
3988 }
3989
3990 return;
3991 }
3992
3993 S.Diag(loc, diag::err_arc_mismatched_cast)
3994 << !convKindForDiag
3995 << srcKind << castExprType << castType
3996 << castRange << castExpr->getSourceRange();
3997 }
3998
3999 template <typename TB>
CheckObjCBridgeNSCast(Sema & S,QualType castType,Expr * castExpr,bool & HadTheAttribute,bool warn)4000 static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr,
4001 bool &HadTheAttribute, bool warn) {
4002 QualType T = castExpr->getType();
4003 HadTheAttribute = false;
4004 while (const auto *TD = T->getAs<TypedefType>()) {
4005 TypedefNameDecl *TDNDecl = TD->getDecl();
4006 if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
4007 if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
4008 HadTheAttribute = true;
4009 if (Parm->isStr("id"))
4010 return true;
4011
4012 // Check for an existing type with this name.
4013 LookupResult R(S, DeclarationName(Parm), SourceLocation(),
4014 Sema::LookupOrdinaryName);
4015 if (S.LookupName(R, S.TUScope)) {
4016 NamedDecl *Target = R.getFoundDecl();
4017 if (Target && isa<ObjCInterfaceDecl>(Target)) {
4018 ObjCInterfaceDecl *ExprClass = cast<ObjCInterfaceDecl>(Target);
4019 if (const ObjCObjectPointerType *InterfacePointerType =
4020 castType->getAsObjCInterfacePointerType()) {
4021 ObjCInterfaceDecl *CastClass
4022 = InterfacePointerType->getObjectType()->getInterface();
4023 if ((CastClass == ExprClass) ||
4024 (CastClass && CastClass->isSuperClassOf(ExprClass)))
4025 return true;
4026 if (warn)
4027 S.Diag(castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4028 << T << Target->getName() << castType->getPointeeType();
4029 return false;
4030 } else if (castType->isObjCIdType() ||
4031 (S.Context.ObjCObjectAdoptsQTypeProtocols(
4032 castType, ExprClass)))
4033 // ok to cast to 'id'.
4034 // casting to id<p-list> is ok if bridge type adopts all of
4035 // p-list protocols.
4036 return true;
4037 else {
4038 if (warn) {
4039 S.Diag(castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4040 << T << Target->getName() << castType;
4041 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4042 S.Diag(Target->getBeginLoc(), diag::note_declared_at);
4043 }
4044 return false;
4045 }
4046 }
4047 } else if (!castType->isObjCIdType()) {
4048 S.Diag(castExpr->getBeginLoc(),
4049 diag::err_objc_cf_bridged_not_interface)
4050 << castExpr->getType() << Parm;
4051 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4052 }
4053 return true;
4054 }
4055 return false;
4056 }
4057 T = TDNDecl->getUnderlyingType();
4058 }
4059 return true;
4060 }
4061
4062 template <typename TB>
CheckObjCBridgeCFCast(Sema & S,QualType castType,Expr * castExpr,bool & HadTheAttribute,bool warn)4063 static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr,
4064 bool &HadTheAttribute, bool warn) {
4065 QualType T = castType;
4066 HadTheAttribute = false;
4067 while (const auto *TD = T->getAs<TypedefType>()) {
4068 TypedefNameDecl *TDNDecl = TD->getDecl();
4069 if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
4070 if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
4071 HadTheAttribute = true;
4072 if (Parm->isStr("id"))
4073 return true;
4074
4075 NamedDecl *Target = nullptr;
4076 // Check for an existing type with this name.
4077 LookupResult R(S, DeclarationName(Parm), SourceLocation(),
4078 Sema::LookupOrdinaryName);
4079 if (S.LookupName(R, S.TUScope)) {
4080 Target = R.getFoundDecl();
4081 if (Target && isa<ObjCInterfaceDecl>(Target)) {
4082 ObjCInterfaceDecl *CastClass = cast<ObjCInterfaceDecl>(Target);
4083 if (const ObjCObjectPointerType *InterfacePointerType =
4084 castExpr->getType()->getAsObjCInterfacePointerType()) {
4085 ObjCInterfaceDecl *ExprClass
4086 = InterfacePointerType->getObjectType()->getInterface();
4087 if ((CastClass == ExprClass) ||
4088 (ExprClass && CastClass->isSuperClassOf(ExprClass)))
4089 return true;
4090 if (warn) {
4091 S.Diag(castExpr->getBeginLoc(),
4092 diag::warn_objc_invalid_bridge_to_cf)
4093 << castExpr->getType()->getPointeeType() << T;
4094 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4095 }
4096 return false;
4097 } else if (castExpr->getType()->isObjCIdType() ||
4098 (S.Context.QIdProtocolsAdoptObjCObjectProtocols(
4099 castExpr->getType(), CastClass)))
4100 // ok to cast an 'id' expression to a CFtype.
4101 // ok to cast an 'id<plist>' expression to CFtype provided plist
4102 // adopts all of CFtype's ObjetiveC's class plist.
4103 return true;
4104 else {
4105 if (warn) {
4106 S.Diag(castExpr->getBeginLoc(),
4107 diag::warn_objc_invalid_bridge_to_cf)
4108 << castExpr->getType() << castType;
4109 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4110 S.Diag(Target->getBeginLoc(), diag::note_declared_at);
4111 }
4112 return false;
4113 }
4114 }
4115 }
4116 S.Diag(castExpr->getBeginLoc(),
4117 diag::err_objc_ns_bridged_invalid_cfobject)
4118 << castExpr->getType() << castType;
4119 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4120 if (Target)
4121 S.Diag(Target->getBeginLoc(), diag::note_declared_at);
4122 return true;
4123 }
4124 return false;
4125 }
4126 T = TDNDecl->getUnderlyingType();
4127 }
4128 return true;
4129 }
4130
CheckTollFreeBridgeCast(QualType castType,Expr * castExpr)4131 void Sema::CheckTollFreeBridgeCast(QualType castType, Expr *castExpr) {
4132 if (!getLangOpts().ObjC)
4133 return;
4134 // warn in presence of __bridge casting to or from a toll free bridge cast.
4135 ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExpr->getType());
4136 ARCConversionTypeClass castACTC = classifyTypeForARCConversion(castType);
4137 if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) {
4138 bool HasObjCBridgeAttr;
4139 bool ObjCBridgeAttrWillNotWarn =
4140 CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
4141 false);
4142 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4143 return;
4144 bool HasObjCBridgeMutableAttr;
4145 bool ObjCBridgeMutableAttrWillNotWarn =
4146 CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
4147 HasObjCBridgeMutableAttr, false);
4148 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4149 return;
4150
4151 if (HasObjCBridgeAttr)
4152 CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
4153 true);
4154 else if (HasObjCBridgeMutableAttr)
4155 CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
4156 HasObjCBridgeMutableAttr, true);
4157 }
4158 else if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable) {
4159 bool HasObjCBridgeAttr;
4160 bool ObjCBridgeAttrWillNotWarn =
4161 CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
4162 false);
4163 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4164 return;
4165 bool HasObjCBridgeMutableAttr;
4166 bool ObjCBridgeMutableAttrWillNotWarn =
4167 CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
4168 HasObjCBridgeMutableAttr, false);
4169 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4170 return;
4171
4172 if (HasObjCBridgeAttr)
4173 CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
4174 true);
4175 else if (HasObjCBridgeMutableAttr)
4176 CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
4177 HasObjCBridgeMutableAttr, true);
4178 }
4179 }
4180
CheckObjCBridgeRelatedCast(QualType castType,Expr * castExpr)4181 void Sema::CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr) {
4182 QualType SrcType = castExpr->getType();
4183 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(castExpr)) {
4184 if (PRE->isExplicitProperty()) {
4185 if (ObjCPropertyDecl *PDecl = PRE->getExplicitProperty())
4186 SrcType = PDecl->getType();
4187 }
4188 else if (PRE->isImplicitProperty()) {
4189 if (ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter())
4190 SrcType = Getter->getReturnType();
4191 }
4192 }
4193
4194 ARCConversionTypeClass srcExprACTC = classifyTypeForARCConversion(SrcType);
4195 ARCConversionTypeClass castExprACTC = classifyTypeForARCConversion(castType);
4196 if (srcExprACTC != ACTC_retainable || castExprACTC != ACTC_coreFoundation)
4197 return;
4198 CheckObjCBridgeRelatedConversions(castExpr->getBeginLoc(), castType, SrcType,
4199 castExpr);
4200 }
4201
CheckTollFreeBridgeStaticCast(QualType castType,Expr * castExpr,CastKind & Kind)4202 bool Sema::CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr,
4203 CastKind &Kind) {
4204 if (!getLangOpts().ObjC)
4205 return false;
4206 ARCConversionTypeClass exprACTC =
4207 classifyTypeForARCConversion(castExpr->getType());
4208 ARCConversionTypeClass castACTC = classifyTypeForARCConversion(castType);
4209 if ((castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) ||
4210 (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable)) {
4211 CheckTollFreeBridgeCast(castType, castExpr);
4212 Kind = (castACTC == ACTC_coreFoundation) ? CK_BitCast
4213 : CK_CPointerToObjCPointerCast;
4214 return true;
4215 }
4216 return false;
4217 }
4218
checkObjCBridgeRelatedComponents(SourceLocation Loc,QualType DestType,QualType SrcType,ObjCInterfaceDecl * & RelatedClass,ObjCMethodDecl * & ClassMethod,ObjCMethodDecl * & InstanceMethod,TypedefNameDecl * & TDNDecl,bool CfToNs,bool Diagnose)4219 bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
4220 QualType DestType, QualType SrcType,
4221 ObjCInterfaceDecl *&RelatedClass,
4222 ObjCMethodDecl *&ClassMethod,
4223 ObjCMethodDecl *&InstanceMethod,
4224 TypedefNameDecl *&TDNDecl,
4225 bool CfToNs, bool Diagnose) {
4226 QualType T = CfToNs ? SrcType : DestType;
4227 ObjCBridgeRelatedAttr *ObjCBAttr = ObjCBridgeRelatedAttrFromType(T, TDNDecl);
4228 if (!ObjCBAttr)
4229 return false;
4230
4231 IdentifierInfo *RCId = ObjCBAttr->getRelatedClass();
4232 IdentifierInfo *CMId = ObjCBAttr->getClassMethod();
4233 IdentifierInfo *IMId = ObjCBAttr->getInstanceMethod();
4234 if (!RCId)
4235 return false;
4236 NamedDecl *Target = nullptr;
4237 // Check for an existing type with this name.
4238 LookupResult R(*this, DeclarationName(RCId), SourceLocation(),
4239 Sema::LookupOrdinaryName);
4240 if (!LookupName(R, TUScope)) {
4241 if (Diagnose) {
4242 Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId
4243 << SrcType << DestType;
4244 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4245 }
4246 return false;
4247 }
4248 Target = R.getFoundDecl();
4249 if (Target && isa<ObjCInterfaceDecl>(Target))
4250 RelatedClass = cast<ObjCInterfaceDecl>(Target);
4251 else {
4252 if (Diagnose) {
4253 Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId
4254 << SrcType << DestType;
4255 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4256 if (Target)
4257 Diag(Target->getBeginLoc(), diag::note_declared_at);
4258 }
4259 return false;
4260 }
4261
4262 // Check for an existing class method with the given selector name.
4263 if (CfToNs && CMId) {
4264 Selector Sel = Context.Selectors.getUnarySelector(CMId);
4265 ClassMethod = RelatedClass->lookupMethod(Sel, false);
4266 if (!ClassMethod) {
4267 if (Diagnose) {
4268 Diag(Loc, diag::err_objc_bridged_related_known_method)
4269 << SrcType << DestType << Sel << false;
4270 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4271 }
4272 return false;
4273 }
4274 }
4275
4276 // Check for an existing instance method with the given selector name.
4277 if (!CfToNs && IMId) {
4278 Selector Sel = Context.Selectors.getNullarySelector(IMId);
4279 InstanceMethod = RelatedClass->lookupMethod(Sel, true);
4280 if (!InstanceMethod) {
4281 if (Diagnose) {
4282 Diag(Loc, diag::err_objc_bridged_related_known_method)
4283 << SrcType << DestType << Sel << true;
4284 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4285 }
4286 return false;
4287 }
4288 }
4289 return true;
4290 }
4291
4292 bool
CheckObjCBridgeRelatedConversions(SourceLocation Loc,QualType DestType,QualType SrcType,Expr * & SrcExpr,bool Diagnose)4293 Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
4294 QualType DestType, QualType SrcType,
4295 Expr *&SrcExpr, bool Diagnose) {
4296 ARCConversionTypeClass rhsExprACTC = classifyTypeForARCConversion(SrcType);
4297 ARCConversionTypeClass lhsExprACTC = classifyTypeForARCConversion(DestType);
4298 bool CfToNs = (rhsExprACTC == ACTC_coreFoundation && lhsExprACTC == ACTC_retainable);
4299 bool NsToCf = (rhsExprACTC == ACTC_retainable && lhsExprACTC == ACTC_coreFoundation);
4300 if (!CfToNs && !NsToCf)
4301 return false;
4302
4303 ObjCInterfaceDecl *RelatedClass;
4304 ObjCMethodDecl *ClassMethod = nullptr;
4305 ObjCMethodDecl *InstanceMethod = nullptr;
4306 TypedefNameDecl *TDNDecl = nullptr;
4307 if (!checkObjCBridgeRelatedComponents(Loc, DestType, SrcType, RelatedClass,
4308 ClassMethod, InstanceMethod, TDNDecl,
4309 CfToNs, Diagnose))
4310 return false;
4311
4312 if (CfToNs) {
4313 // Implicit conversion from CF to ObjC object is needed.
4314 if (ClassMethod) {
4315 if (Diagnose) {
4316 std::string ExpressionString = "[";
4317 ExpressionString += RelatedClass->getNameAsString();
4318 ExpressionString += " ";
4319 ExpressionString += ClassMethod->getSelector().getAsString();
4320 SourceLocation SrcExprEndLoc =
4321 getLocForEndOfToken(SrcExpr->getEndLoc());
4322 // Provide a fixit: [RelatedClass ClassMethod SrcExpr]
4323 Diag(Loc, diag::err_objc_bridged_related_known_method)
4324 << SrcType << DestType << ClassMethod->getSelector() << false
4325 << FixItHint::CreateInsertion(SrcExpr->getBeginLoc(),
4326 ExpressionString)
4327 << FixItHint::CreateInsertion(SrcExprEndLoc, "]");
4328 Diag(RelatedClass->getBeginLoc(), diag::note_declared_at);
4329 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4330
4331 QualType receiverType = Context.getObjCInterfaceType(RelatedClass);
4332 // Argument.
4333 Expr *args[] = { SrcExpr };
4334 ExprResult msg = BuildClassMessageImplicit(receiverType, false,
4335 ClassMethod->getLocation(),
4336 ClassMethod->getSelector(), ClassMethod,
4337 MultiExprArg(args, 1));
4338 SrcExpr = msg.get();
4339 }
4340 return true;
4341 }
4342 }
4343 else {
4344 // Implicit conversion from ObjC type to CF object is needed.
4345 if (InstanceMethod) {
4346 if (Diagnose) {
4347 std::string ExpressionString;
4348 SourceLocation SrcExprEndLoc =
4349 getLocForEndOfToken(SrcExpr->getEndLoc());
4350 if (InstanceMethod->isPropertyAccessor())
4351 if (const ObjCPropertyDecl *PDecl =
4352 InstanceMethod->findPropertyDecl()) {
4353 // fixit: ObjectExpr.propertyname when it is aproperty accessor.
4354 ExpressionString = ".";
4355 ExpressionString += PDecl->getNameAsString();
4356 Diag(Loc, diag::err_objc_bridged_related_known_method)
4357 << SrcType << DestType << InstanceMethod->getSelector() << true
4358 << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
4359 }
4360 if (ExpressionString.empty()) {
4361 // Provide a fixit: [ObjectExpr InstanceMethod]
4362 ExpressionString = " ";
4363 ExpressionString += InstanceMethod->getSelector().getAsString();
4364 ExpressionString += "]";
4365
4366 Diag(Loc, diag::err_objc_bridged_related_known_method)
4367 << SrcType << DestType << InstanceMethod->getSelector() << true
4368 << FixItHint::CreateInsertion(SrcExpr->getBeginLoc(), "[")
4369 << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
4370 }
4371 Diag(RelatedClass->getBeginLoc(), diag::note_declared_at);
4372 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4373
4374 ExprResult msg = BuildInstanceMessageImplicit(
4375 SrcExpr, SrcType, InstanceMethod->getLocation(),
4376 InstanceMethod->getSelector(), InstanceMethod, std::nullopt);
4377 SrcExpr = msg.get();
4378 }
4379 return true;
4380 }
4381 }
4382 return false;
4383 }
4384
4385 Sema::ARCConversionResult
CheckObjCConversion(SourceRange castRange,QualType castType,Expr * & castExpr,CheckedConversionKind CCK,bool Diagnose,bool DiagnoseCFAudited,BinaryOperatorKind Opc)4386 Sema::CheckObjCConversion(SourceRange castRange, QualType castType,
4387 Expr *&castExpr, CheckedConversionKind CCK,
4388 bool Diagnose, bool DiagnoseCFAudited,
4389 BinaryOperatorKind Opc) {
4390 QualType castExprType = castExpr->getType();
4391
4392 // For the purposes of the classification, we assume reference types
4393 // will bind to temporaries.
4394 QualType effCastType = castType;
4395 if (const ReferenceType *ref = castType->getAs<ReferenceType>())
4396 effCastType = ref->getPointeeType();
4397
4398 ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExprType);
4399 ARCConversionTypeClass castACTC = classifyTypeForARCConversion(effCastType);
4400 if (exprACTC == castACTC) {
4401 // Check for viability and report error if casting an rvalue to a
4402 // life-time qualifier.
4403 if (castACTC == ACTC_retainable &&
4404 (CCK == CCK_CStyleCast || CCK == CCK_OtherCast) &&
4405 castType != castExprType) {
4406 const Type *DT = castType.getTypePtr();
4407 QualType QDT = castType;
4408 // We desugar some types but not others. We ignore those
4409 // that cannot happen in a cast; i.e. auto, and those which
4410 // should not be de-sugared; i.e typedef.
4411 if (const ParenType *PT = dyn_cast<ParenType>(DT))
4412 QDT = PT->desugar();
4413 else if (const TypeOfType *TP = dyn_cast<TypeOfType>(DT))
4414 QDT = TP->desugar();
4415 else if (const AttributedType *AT = dyn_cast<AttributedType>(DT))
4416 QDT = AT->desugar();
4417 if (QDT != castType &&
4418 QDT.getObjCLifetime() != Qualifiers::OCL_None) {
4419 if (Diagnose) {
4420 SourceLocation loc = (castRange.isValid() ? castRange.getBegin()
4421 : castExpr->getExprLoc());
4422 Diag(loc, diag::err_arc_nolifetime_behavior);
4423 }
4424 return ACR_error;
4425 }
4426 }
4427 return ACR_okay;
4428 }
4429
4430 // The life-time qualifier cast check above is all we need for ObjCWeak.
4431 // ObjCAutoRefCount has more restrictions on what is legal.
4432 if (!getLangOpts().ObjCAutoRefCount)
4433 return ACR_okay;
4434
4435 if (isAnyCLike(exprACTC) && isAnyCLike(castACTC)) return ACR_okay;
4436
4437 // Allow all of these types to be cast to integer types (but not
4438 // vice-versa).
4439 if (castACTC == ACTC_none && castType->isIntegralType(Context))
4440 return ACR_okay;
4441
4442 // Allow casts between pointers to lifetime types (e.g., __strong id*)
4443 // and pointers to void (e.g., cv void *). Casting from void* to lifetime*
4444 // must be explicit.
4445 // Allow conversions between pointers to lifetime types and coreFoundation
4446 // pointers too, but only when the conversions are explicit.
4447 if (exprACTC == ACTC_indirectRetainable &&
4448 (castACTC == ACTC_voidPtr ||
4449 (castACTC == ACTC_coreFoundation && isCast(CCK))))
4450 return ACR_okay;
4451 if (castACTC == ACTC_indirectRetainable &&
4452 (exprACTC == ACTC_voidPtr || exprACTC == ACTC_coreFoundation) &&
4453 isCast(CCK))
4454 return ACR_okay;
4455
4456 switch (ARCCastChecker(Context, exprACTC, castACTC, false).Visit(castExpr)) {
4457 // For invalid casts, fall through.
4458 case ACC_invalid:
4459 break;
4460
4461 // Do nothing for both bottom and +0.
4462 case ACC_bottom:
4463 case ACC_plusZero:
4464 return ACR_okay;
4465
4466 // If the result is +1, consume it here.
4467 case ACC_plusOne:
4468 castExpr = ImplicitCastExpr::Create(Context, castExpr->getType(),
4469 CK_ARCConsumeObject, castExpr, nullptr,
4470 VK_PRValue, FPOptionsOverride());
4471 Cleanup.setExprNeedsCleanups(true);
4472 return ACR_okay;
4473 }
4474
4475 // If this is a non-implicit cast from id or block type to a
4476 // CoreFoundation type, delay complaining in case the cast is used
4477 // in an acceptable context.
4478 if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC) && isCast(CCK))
4479 return ACR_unbridged;
4480
4481 // Issue a diagnostic about a missing @-sign when implicit casting a cstring
4482 // to 'NSString *', instead of falling through to report a "bridge cast"
4483 // diagnostic.
4484 if (castACTC == ACTC_retainable && exprACTC == ACTC_none &&
4485 CheckConversionToObjCLiteral(castType, castExpr, Diagnose))
4486 return ACR_error;
4487
4488 // Do not issue "bridge cast" diagnostic when implicit casting
4489 // a retainable object to a CF type parameter belonging to an audited
4490 // CF API function. Let caller issue a normal type mismatched diagnostic
4491 // instead.
4492 if ((!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
4493 castACTC != ACTC_coreFoundation) &&
4494 !(exprACTC == ACTC_voidPtr && castACTC == ACTC_retainable &&
4495 (Opc == BO_NE || Opc == BO_EQ))) {
4496 if (Diagnose)
4497 diagnoseObjCARCConversion(*this, castRange, castType, castACTC, castExpr,
4498 castExpr, exprACTC, CCK);
4499 return ACR_error;
4500 }
4501 return ACR_okay;
4502 }
4503
4504 /// Given that we saw an expression with the ARCUnbridgedCastTy
4505 /// placeholder type, complain bitterly.
diagnoseARCUnbridgedCast(Expr * e)4506 void Sema::diagnoseARCUnbridgedCast(Expr *e) {
4507 // We expect the spurious ImplicitCastExpr to already have been stripped.
4508 assert(!e->hasPlaceholderType(BuiltinType::ARCUnbridgedCast));
4509 CastExpr *realCast = cast<CastExpr>(e->IgnoreParens());
4510
4511 SourceRange castRange;
4512 QualType castType;
4513 CheckedConversionKind CCK;
4514
4515 if (CStyleCastExpr *cast = dyn_cast<CStyleCastExpr>(realCast)) {
4516 castRange = SourceRange(cast->getLParenLoc(), cast->getRParenLoc());
4517 castType = cast->getTypeAsWritten();
4518 CCK = CCK_CStyleCast;
4519 } else if (ExplicitCastExpr *cast = dyn_cast<ExplicitCastExpr>(realCast)) {
4520 castRange = cast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange();
4521 castType = cast->getTypeAsWritten();
4522 CCK = CCK_OtherCast;
4523 } else {
4524 llvm_unreachable("Unexpected ImplicitCastExpr");
4525 }
4526
4527 ARCConversionTypeClass castACTC =
4528 classifyTypeForARCConversion(castType.getNonReferenceType());
4529
4530 Expr *castExpr = realCast->getSubExpr();
4531 assert(classifyTypeForARCConversion(castExpr->getType()) == ACTC_retainable);
4532
4533 diagnoseObjCARCConversion(*this, castRange, castType, castACTC,
4534 castExpr, realCast, ACTC_retainable, CCK);
4535 }
4536
4537 /// stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast
4538 /// type, remove the placeholder cast.
stripARCUnbridgedCast(Expr * e)4539 Expr *Sema::stripARCUnbridgedCast(Expr *e) {
4540 assert(e->hasPlaceholderType(BuiltinType::ARCUnbridgedCast));
4541
4542 if (ParenExpr *pe = dyn_cast<ParenExpr>(e)) {
4543 Expr *sub = stripARCUnbridgedCast(pe->getSubExpr());
4544 return new (Context) ParenExpr(pe->getLParen(), pe->getRParen(), sub);
4545 } else if (UnaryOperator *uo = dyn_cast<UnaryOperator>(e)) {
4546 assert(uo->getOpcode() == UO_Extension);
4547 Expr *sub = stripARCUnbridgedCast(uo->getSubExpr());
4548 return UnaryOperator::Create(Context, sub, UO_Extension, sub->getType(),
4549 sub->getValueKind(), sub->getObjectKind(),
4550 uo->getOperatorLoc(), false,
4551 CurFPFeatureOverrides());
4552 } else if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {
4553 assert(!gse->isResultDependent());
4554
4555 unsigned n = gse->getNumAssocs();
4556 SmallVector<Expr *, 4> subExprs;
4557 SmallVector<TypeSourceInfo *, 4> subTypes;
4558 subExprs.reserve(n);
4559 subTypes.reserve(n);
4560 for (const GenericSelectionExpr::Association assoc : gse->associations()) {
4561 subTypes.push_back(assoc.getTypeSourceInfo());
4562 Expr *sub = assoc.getAssociationExpr();
4563 if (assoc.isSelected())
4564 sub = stripARCUnbridgedCast(sub);
4565 subExprs.push_back(sub);
4566 }
4567
4568 return GenericSelectionExpr::Create(
4569 Context, gse->getGenericLoc(), gse->getControllingExpr(), subTypes,
4570 subExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
4571 gse->containsUnexpandedParameterPack(), gse->getResultIndex());
4572 } else {
4573 assert(isa<ImplicitCastExpr>(e) && "bad form of unbridged cast!");
4574 return cast<ImplicitCastExpr>(e)->getSubExpr();
4575 }
4576 }
4577
CheckObjCARCUnavailableWeakConversion(QualType castType,QualType exprType)4578 bool Sema::CheckObjCARCUnavailableWeakConversion(QualType castType,
4579 QualType exprType) {
4580 QualType canCastType =
4581 Context.getCanonicalType(castType).getUnqualifiedType();
4582 QualType canExprType =
4583 Context.getCanonicalType(exprType).getUnqualifiedType();
4584 if (isa<ObjCObjectPointerType>(canCastType) &&
4585 castType.getObjCLifetime() == Qualifiers::OCL_Weak &&
4586 canExprType->isObjCObjectPointerType()) {
4587 if (const ObjCObjectPointerType *ObjT =
4588 canExprType->getAs<ObjCObjectPointerType>())
4589 if (const ObjCInterfaceDecl *ObjI = ObjT->getInterfaceDecl())
4590 return !ObjI->isArcWeakrefUnavailable();
4591 }
4592 return true;
4593 }
4594
4595 /// Look for an ObjCReclaimReturnedObject cast and destroy it.
maybeUndoReclaimObject(Expr * e)4596 static Expr *maybeUndoReclaimObject(Expr *e) {
4597 Expr *curExpr = e, *prevExpr = nullptr;
4598
4599 // Walk down the expression until we hit an implicit cast of kind
4600 // ARCReclaimReturnedObject or an Expr that is neither a Paren nor a Cast.
4601 while (true) {
4602 if (auto *pe = dyn_cast<ParenExpr>(curExpr)) {
4603 prevExpr = curExpr;
4604 curExpr = pe->getSubExpr();
4605 continue;
4606 }
4607
4608 if (auto *ce = dyn_cast<CastExpr>(curExpr)) {
4609 if (auto *ice = dyn_cast<ImplicitCastExpr>(ce))
4610 if (ice->getCastKind() == CK_ARCReclaimReturnedObject) {
4611 if (!prevExpr)
4612 return ice->getSubExpr();
4613 if (auto *pe = dyn_cast<ParenExpr>(prevExpr))
4614 pe->setSubExpr(ice->getSubExpr());
4615 else
4616 cast<CastExpr>(prevExpr)->setSubExpr(ice->getSubExpr());
4617 return e;
4618 }
4619
4620 prevExpr = curExpr;
4621 curExpr = ce->getSubExpr();
4622 continue;
4623 }
4624
4625 // Break out of the loop if curExpr is neither a Paren nor a Cast.
4626 break;
4627 }
4628
4629 return e;
4630 }
4631
BuildObjCBridgedCast(SourceLocation LParenLoc,ObjCBridgeCastKind Kind,SourceLocation BridgeKeywordLoc,TypeSourceInfo * TSInfo,Expr * SubExpr)4632 ExprResult Sema::BuildObjCBridgedCast(SourceLocation LParenLoc,
4633 ObjCBridgeCastKind Kind,
4634 SourceLocation BridgeKeywordLoc,
4635 TypeSourceInfo *TSInfo,
4636 Expr *SubExpr) {
4637 ExprResult SubResult = UsualUnaryConversions(SubExpr);
4638 if (SubResult.isInvalid()) return ExprError();
4639 SubExpr = SubResult.get();
4640
4641 QualType T = TSInfo->getType();
4642 QualType FromType = SubExpr->getType();
4643
4644 CastKind CK;
4645
4646 bool MustConsume = false;
4647 if (T->isDependentType() || SubExpr->isTypeDependent()) {
4648 // Okay: we'll build a dependent expression type.
4649 CK = CK_Dependent;
4650 } else if (T->isObjCARCBridgableType() && FromType->isCARCBridgableType()) {
4651 // Casting CF -> id
4652 CK = (T->isBlockPointerType() ? CK_AnyPointerToBlockPointerCast
4653 : CK_CPointerToObjCPointerCast);
4654 switch (Kind) {
4655 case OBC_Bridge:
4656 break;
4657
4658 case OBC_BridgeRetained: {
4659 bool br = isKnownName("CFBridgingRelease");
4660 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4661 << 2
4662 << FromType
4663 << (T->isBlockPointerType()? 1 : 0)
4664 << T
4665 << SubExpr->getSourceRange()
4666 << Kind;
4667 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4668 << FixItHint::CreateReplacement(BridgeKeywordLoc, "__bridge");
4669 Diag(BridgeKeywordLoc, diag::note_arc_bridge_transfer)
4670 << FromType << br
4671 << FixItHint::CreateReplacement(BridgeKeywordLoc,
4672 br ? "CFBridgingRelease "
4673 : "__bridge_transfer ");
4674
4675 Kind = OBC_Bridge;
4676 break;
4677 }
4678
4679 case OBC_BridgeTransfer:
4680 // We must consume the Objective-C object produced by the cast.
4681 MustConsume = true;
4682 break;
4683 }
4684 } else if (T->isCARCBridgableType() && FromType->isObjCARCBridgableType()) {
4685 // Okay: id -> CF
4686 CK = CK_BitCast;
4687 switch (Kind) {
4688 case OBC_Bridge:
4689 // Reclaiming a value that's going to be __bridge-casted to CF
4690 // is very dangerous, so we don't do it.
4691 SubExpr = maybeUndoReclaimObject(SubExpr);
4692 break;
4693
4694 case OBC_BridgeRetained:
4695 // Produce the object before casting it.
4696 SubExpr = ImplicitCastExpr::Create(Context, FromType, CK_ARCProduceObject,
4697 SubExpr, nullptr, VK_PRValue,
4698 FPOptionsOverride());
4699 break;
4700
4701 case OBC_BridgeTransfer: {
4702 bool br = isKnownName("CFBridgingRetain");
4703 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4704 << (FromType->isBlockPointerType()? 1 : 0)
4705 << FromType
4706 << 2
4707 << T
4708 << SubExpr->getSourceRange()
4709 << Kind;
4710
4711 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4712 << FixItHint::CreateReplacement(BridgeKeywordLoc, "__bridge ");
4713 Diag(BridgeKeywordLoc, diag::note_arc_bridge_retained)
4714 << T << br
4715 << FixItHint::CreateReplacement(BridgeKeywordLoc,
4716 br ? "CFBridgingRetain " : "__bridge_retained");
4717
4718 Kind = OBC_Bridge;
4719 break;
4720 }
4721 }
4722 } else {
4723 Diag(LParenLoc, diag::err_arc_bridge_cast_incompatible)
4724 << FromType << T << Kind
4725 << SubExpr->getSourceRange()
4726 << TSInfo->getTypeLoc().getSourceRange();
4727 return ExprError();
4728 }
4729
4730 Expr *Result = new (Context) ObjCBridgedCastExpr(LParenLoc, Kind, CK,
4731 BridgeKeywordLoc,
4732 TSInfo, SubExpr);
4733
4734 if (MustConsume) {
4735 Cleanup.setExprNeedsCleanups(true);
4736 Result = ImplicitCastExpr::Create(Context, T, CK_ARCConsumeObject, Result,
4737 nullptr, VK_PRValue, FPOptionsOverride());
4738 }
4739
4740 return Result;
4741 }
4742
ActOnObjCBridgedCast(Scope * S,SourceLocation LParenLoc,ObjCBridgeCastKind Kind,SourceLocation BridgeKeywordLoc,ParsedType Type,SourceLocation RParenLoc,Expr * SubExpr)4743 ExprResult Sema::ActOnObjCBridgedCast(Scope *S,
4744 SourceLocation LParenLoc,
4745 ObjCBridgeCastKind Kind,
4746 SourceLocation BridgeKeywordLoc,
4747 ParsedType Type,
4748 SourceLocation RParenLoc,
4749 Expr *SubExpr) {
4750 TypeSourceInfo *TSInfo = nullptr;
4751 QualType T = GetTypeFromParser(Type, &TSInfo);
4752 if (Kind == OBC_Bridge)
4753 CheckTollFreeBridgeCast(T, SubExpr);
4754 if (!TSInfo)
4755 TSInfo = Context.getTrivialTypeSourceInfo(T, LParenLoc);
4756 return BuildObjCBridgedCast(LParenLoc, Kind, BridgeKeywordLoc, TSInfo,
4757 SubExpr);
4758 }
4759