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

source code of clang/lib/Sema/SemaExprObjC.cpp