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

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