clang 23.0.0git
SemaExprObjC.cpp
Go to the documentation of this file.
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
15#include "clang/AST/DeclObjC.h"
16#include "clang/AST/ExprObjC.h"
18#include "clang/AST/TypeLoc.h"
22#include "clang/Edit/Commit.h"
26#include "clang/Sema/Lookup.h"
27#include "clang/Sema/Scope.h"
29#include "clang/Sema/SemaObjC.h"
30#include "llvm/Support/ConvertUTF.h"
31#include <optional>
32
33using namespace clang;
34using namespace sema;
35using llvm::APFloat;
36using llvm::ArrayRef;
37
39 ArrayRef<Expr *> Strings) {
40 ASTContext &Context = getASTContext();
41 // Most ObjC strings are formed out of a single piece. However, we *can*
42 // have strings formed out of multiple @ strings with multiple pptokens in
43 // each one, e.g. @"foo" "bar" @"baz" "qux" which need to be turned into one
44 // StringLiteral for ObjCStringLiteral to hold onto.
45 StringLiteral *S = cast<StringLiteral>(Strings[0]);
46
47 // If we have a multi-part string, merge it all together.
48 if (Strings.size() != 1) {
49 // Concatenate objc strings.
50 SmallString<128> StrBuf;
52
53 for (Expr *E : Strings) {
55
56 // ObjC strings can't be wide or UTF.
57 if (!S->isOrdinary()) {
58 Diag(S->getBeginLoc(), diag::err_cfstring_literal_not_string_constant)
59 << S->getSourceRange();
60 return true;
61 }
62
63 // Append the string.
64 StrBuf += S->getString();
65
66 // Get the locations of the string tokens.
67 StrLocs.append(S->tokloc_begin(), S->tokloc_end());
68 }
69
70 // Create the aggregate string with the appropriate content and location
71 // information.
72 const ConstantArrayType *CAT = Context.getAsConstantArrayType(S->getType());
73 assert(CAT && "String literal not of constant array type!");
74 QualType StrTy = Context.getConstantArrayType(
75 CAT->getElementType(), llvm::APInt(32, StrBuf.size() + 1), nullptr,
78 /*Pascal=*/false, StrTy, StrLocs);
79 }
80
81 return BuildObjCStringLiteral(AtLocs[0], S);
82}
83
85 StringLiteral *S) {
86 ASTContext &Context = getASTContext();
87 // Verify that this composite string is acceptable for ObjC strings.
88 if (CheckObjCString(S))
89 return true;
90
91 // Initialize the constant string interface lazily. This assumes
92 // the NSString interface is seen in this translation unit. Note: We
93 // don't use NSConstantString, since the runtime team considers this
94 // interface private (even though it appears in the header files).
95 QualType Ty = Context.getObjCConstantStringInterface();
96 if (!Ty.isNull()) {
97 Ty = Context.getObjCObjectPointerType(Ty);
98 } else if (getLangOpts().NoConstantCFStrings) {
99 IdentifierInfo *NSIdent=nullptr;
100 std::string StringClass(getLangOpts().ObjCConstantStringClass);
101
102 if (StringClass.empty())
103 NSIdent = &Context.Idents.get("NSConstantString");
104 else
105 NSIdent = &Context.Idents.get(StringClass);
106
107 NamedDecl *IF = SemaRef.LookupSingleName(SemaRef.TUScope, NSIdent, AtLoc,
109 if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
110 Context.setObjCConstantStringInterface(StrIF);
111 Ty = Context.getObjCConstantStringInterface();
112 Ty = Context.getObjCObjectPointerType(Ty);
113 } else {
114 // If there is no NSConstantString interface defined then treat this
115 // as error and recover from it.
116 Diag(S->getBeginLoc(), diag::err_no_nsconstant_string_class)
117 << NSIdent << S->getSourceRange();
118 Ty = Context.getObjCIdType();
119 }
120 } else {
121 IdentifierInfo *NSIdent = NSAPIObj->getNSClassId(NSAPI::ClassId_NSString);
122 NamedDecl *IF = SemaRef.LookupSingleName(SemaRef.TUScope, NSIdent, AtLoc,
124 if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
125 Context.setObjCConstantStringInterface(StrIF);
126 Ty = Context.getObjCConstantStringInterface();
127 Ty = Context.getObjCObjectPointerType(Ty);
128 } else {
129 // If there is no NSString interface defined, implicitly declare
130 // a @class NSString; and use that instead. This is to make sure
131 // type of an NSString literal is represented correctly, instead of
132 // being an 'id' type.
133 Ty = Context.getObjCNSStringType();
134 if (Ty.isNull()) {
135 ObjCInterfaceDecl *NSStringIDecl =
137 Context.getTranslationUnitDecl(),
138 SourceLocation(), NSIdent,
139 nullptr, nullptr, SourceLocation());
140 Ty = Context.getObjCInterfaceType(NSStringIDecl);
141 Context.setObjCNSStringType(Ty);
142 }
143 Ty = Context.getObjCObjectPointerType(Ty);
144 }
145 }
146
147 return new (Context) ObjCStringLiteral(S, Ty, AtLoc);
148}
149
150/// Emits an error if the given method does not exist, or if the return
151/// type is not an Objective-C object.
153 const ObjCInterfaceDecl *Class,
154 Selector Sel, const ObjCMethodDecl *Method) {
155 if (!Method) {
156 // FIXME: Is there a better way to avoid quotes than using getName()?
157 S.Diag(Loc, diag::err_undeclared_boxing_method) << Sel << Class->getName();
158 return false;
159 }
160
161 // Make sure the return type is reasonable.
162 QualType ReturnType = Method->getReturnType();
163 if (!ReturnType->isObjCObjectPointerType()) {
164 S.Diag(Loc, diag::err_objc_literal_method_sig)
165 << Sel;
166 S.Diag(Method->getLocation(), diag::note_objc_literal_method_return)
167 << ReturnType;
168 return false;
169 }
170
171 return true;
172}
173
174/// Maps ObjCLiteralKind to NSClassIdKindKind
177 switch (LiteralKind) {
188
189 // there is no corresponding matching
190 // between LK_None/LK_Block and NSClassIdKindKind
193 break;
194 }
195 llvm_unreachable("LiteralKind can't be converted into a ClassKind");
196}
197
198/// Validates ObjCInterfaceDecl availability.
199/// ObjCInterfaceDecl, used to create ObjC literals, should be defined
200/// if clang not in a debugger mode.
201static bool
203 SourceLocation Loc,
204 SemaObjC::ObjCLiteralKind LiteralKind) {
205 if (!Decl) {
207 IdentifierInfo *II = S.ObjC().NSAPIObj->getNSClassId(Kind);
208 S.Diag(Loc, diag::err_undeclared_objc_literal_class)
209 << II->getName() << LiteralKind;
210 return false;
211 } else if (!Decl->hasDefinition() && !S.getLangOpts().DebuggerObjCLiteral) {
212 S.Diag(Loc, diag::err_undeclared_objc_literal_class)
213 << Decl->getName() << LiteralKind;
214 S.Diag(Decl->getLocation(), diag::note_forward_class);
215 return false;
216 }
217
218 return true;
219}
220
221/// Looks up ObjCInterfaceDecl of a given NSClassIdKindKind.
222/// Used to create ObjC literals, such as NSDictionary (@{}),
223/// NSArray (@[]) and Boxed Expressions (@())
224static ObjCInterfaceDecl *
226 SemaObjC::ObjCLiteralKind LiteralKind) {
227 NSAPI::NSClassIdKindKind ClassKind = ClassKindFromLiteralKind(LiteralKind);
228 IdentifierInfo *II = S.ObjC().NSAPIObj->getNSClassId(ClassKind);
229 NamedDecl *IF = S.LookupSingleName(S.TUScope, II, Loc,
231 ObjCInterfaceDecl *ID = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
232 if (!ID && S.getLangOpts().DebuggerObjCLiteral) {
233 ASTContext &Context = S.Context;
235 ID = ObjCInterfaceDecl::Create (Context, TU, SourceLocation(), II,
236 nullptr, nullptr, SourceLocation());
237 }
238
239 if (!ValidateObjCLiteralInterfaceDecl(S, ID, Loc, LiteralKind)) {
240 ID = nullptr;
241 }
242
243 return ID;
244}
245
246/// Retrieve the NSNumber factory method that should be used to create
247/// an Objective-C literal for the given type.
249 QualType NumberType,
250 bool isLiteral = false,
251 SourceRange R = SourceRange()) {
252 std::optional<NSAPI::NSNumberLiteralMethodKind> Kind =
253 S.NSAPIObj->getNSNumberFactoryMethodKind(NumberType);
254
255 if (!Kind) {
256 if (isLiteral) {
257 S.Diag(Loc, diag::err_invalid_nsnumber_type)
258 << NumberType << R;
259 }
260 return nullptr;
261 }
262
263 // If we already looked up this method, we're done.
264 if (S.NSNumberLiteralMethods[*Kind])
265 return S.NSNumberLiteralMethods[*Kind];
266
267 Selector Sel = S.NSAPIObj->getNSNumberLiteralSelector(*Kind,
268 /*Instance=*/false);
269
270 ASTContext &CX = S.SemaRef.Context;
271
272 // Look up the NSNumber class, if we haven't done so already. It's cached
273 // in the Sema instance.
274 if (!S.NSNumberDecl) {
275 S.NSNumberDecl =
277 if (!S.NSNumberDecl) {
278 return nullptr;
279 }
280 }
281
282 if (S.NSNumberPointer.isNull()) {
283 // generate the pointer to NSNumber type.
284 QualType NSNumberObject = CX.getObjCInterfaceType(S.NSNumberDecl);
285 S.NSNumberPointer = CX.getObjCObjectPointerType(NSNumberObject);
286 }
287
288 // Look for the appropriate method within NSNumber.
290 if (!Method && S.getLangOpts().DebuggerObjCLiteral) {
291 // create a stub definition this NSNumber factory method.
292 TypeSourceInfo *ReturnTInfo = nullptr;
293 Method = ObjCMethodDecl::Create(
295 ReturnTInfo, S.NSNumberDecl,
296 /*isInstance=*/false, /*isVariadic=*/false,
297 /*isPropertyAccessor=*/false,
298 /*isSynthesizedAccessorStub=*/false,
299 /*isImplicitlyDeclared=*/true,
300 /*isDefined=*/false, ObjCImplementationControl::Required,
301 /*HasRelatedResultType=*/false);
302 ParmVarDecl *value =
304 SourceLocation(), &CX.Idents.get("value"),
305 NumberType, /*TInfo=*/nullptr, SC_None, nullptr);
306 Method->setMethodParams(S.SemaRef.Context, value, {});
307 }
308
309 if (!validateBoxingMethod(S.SemaRef, Loc, S.NSNumberDecl, Sel, Method))
310 return nullptr;
311
312 // Note: if the parameter type is out-of-line, we'll catch it later in the
313 // implicit conversion.
314
315 S.NSNumberLiteralMethods[*Kind] = Method;
316 return Method;
317}
318
320 const LangOptions &LangOpts = S.getLangOpts();
321
322 if (!LangOpts.ObjCConstantLiterals)
323 return false;
324
325 const QualType Ty = Number->IgnoreParens()->getType();
326 ASTContext &Context = S.Context;
327
328 if (Number->isValueDependent())
329 return false;
330
331 if (!Number->isEvaluatable(Context))
332 return false;
333
334 // Note `@YES` `@NO` need to be handled explicitly
335 // to meet existing plist encoding / decoding expectations
336 // we can't convert anything that is "bool like" so ensure
337 // we're referring to a `BOOL` typedef or a real `_Bool`
338 // preferring explicit types over the typedefs.
339 //
340 // Also we can emit the constant singleton if supported by the target always.
341 assert(LangOpts.ObjCRuntime.hasConstantCFBooleans() &&
342 "The current ABI doesn't support the constant CFBooleanTrue "
343 "singleton!");
344 const bool IsBoolType =
345 (Ty->isBooleanType() || NSAPI(Context).isObjCBOOLType(Ty));
346 if (IsBoolType)
347 return true;
348
349 // If for debug or other reasons an explict opt-out is passed bail.
350 // This doesn't effect `BOOL` singletons similar to collection singletons.
351 if (!LangOpts.ConstantNSNumberLiterals)
352 return false;
353
354 // Note: Other parts of Sema prevent the boxing of types that aren't supported
355 // by `NSNumber`
356 Expr::EvalResult IntResult{};
357 if (Number->EvaluateAsInt(IntResult, Context))
358 return true;
359
360 // Eval the number as an llvm::APFloat and ensure it fits
361 // what NSNumber expects.
362 APFloat FloatValue(0.0);
363 if (Number->EvaluateAsFloat(FloatValue, Context)) {
364 // This asserts that the sema checks for `ObjCBoxedExpr` haven't changed to
365 // allow larger values than NSNumber supports
366 if (&FloatValue.getSemantics() == &APFloat::IEEEsingle())
367 return true;
368 if (&FloatValue.getSemantics() == &APFloat::IEEEdouble())
369 return true;
370
371 llvm_unreachable(
372 "NSNumber only supports `float` or `double` floating-point types.");
373 }
374
375 return false;
376}
377
378/// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the
379/// numeric literal expression. Type of the expression will be "NSNumber *".
381 Expr *Number) {
382 ASTContext &Context = getASTContext();
383 // Determine the type of the literal.
384 QualType NumberType = Number->getType();
385 if (CharacterLiteral *Char = dyn_cast<CharacterLiteral>(Number)) {
386 // In C, character literals have type 'int'. That's not the type we want
387 // to use to determine the Objective-c literal kind.
388 switch (Char->getKind()) {
391 NumberType = Context.CharTy;
392 break;
393
395 NumberType = Context.getWideCharType();
396 break;
397
399 NumberType = Context.Char16Ty;
400 break;
401
403 NumberType = Context.Char32Ty;
404 break;
405 }
406 }
407
408 // Look for the appropriate method within NSNumber.
409 // Construct the literal.
410 SourceRange NR(Number->getSourceRange());
411 ObjCMethodDecl *Method = getNSNumberFactoryMethod(*this, AtLoc, NumberType,
412 true, NR);
413 if (!Method)
414 return ExprError();
415
416 // Convert the number to the type that the parameter expects.
417 ParmVarDecl *ParamDecl = Method->parameters()[0];
419 ParamDecl);
420 ExprResult ConvertedNumber =
421 SemaRef.PerformCopyInitialization(Entity, SourceLocation(), Number);
422 if (ConvertedNumber.isInvalid())
423 return ExprError();
424 Number = ConvertedNumber.get();
425
426 const bool IsConstInitLiteral =
428
429 auto *NumberLiteral = new (Context)
430 ObjCBoxedExpr(Number, NSNumberPointer, Method, IsConstInitLiteral,
431 SourceRange(AtLoc, NR.getEnd()));
432
433 // Use the effective source range of the literal, including the leading '@'.
434 return SemaRef.MaybeBindToTemporary(NumberLiteral);
435}
436
438 SourceLocation ValueLoc, bool Value) {
439 ASTContext &Context = getASTContext();
440 ExprResult Inner;
441 if (getLangOpts().CPlusPlus) {
442 Inner = SemaRef.ActOnCXXBoolLiteral(ValueLoc,
443 Value ? tok::kw_true : tok::kw_false);
444 } else {
445 // C doesn't actually have a way to represent literal values of type
446 // _Bool. So, we'll use 0/1 and implicit cast to _Bool.
447 Inner = SemaRef.ActOnIntegerConstant(ValueLoc, Value ? 1 : 0);
448 Inner = SemaRef.ImpCastExprToType(Inner.get(), Context.BoolTy,
449 CK_IntegralToBoolean);
450 }
451
452 return BuildObjCNumericLiteral(AtLoc, Inner.get());
453}
454
455/// Check that the given expression is a valid element of an Objective-C
456/// collection literal.
458 QualType T,
459 bool ArrayLiteral = false) {
460 // If the expression is type-dependent, there's nothing for us to do.
461 if (Element->isTypeDependent())
462 return Element;
463
464 ExprResult Result = S.CheckPlaceholderExpr(Element);
465 if (Result.isInvalid())
466 return ExprError();
467 Element = Result.get();
468
469 // In C++, check for an implicit conversion to an Objective-C object pointer
470 // type.
471 if (S.getLangOpts().CPlusPlus && Element->getType()->isRecordType()) {
472 InitializedEntity Entity
474 /*Consumed=*/false);
476 Element->getBeginLoc(), SourceLocation());
477 InitializationSequence Seq(S, Entity, Kind, Element);
478 if (!Seq.Failed())
479 return Seq.Perform(S, Entity, Kind, Element);
480 }
481
482 Expr *OrigElement = Element;
483
484 // Perform lvalue-to-rvalue conversion.
485 Result = S.DefaultLvalueConversion(Element);
486 if (Result.isInvalid())
487 return ExprError();
488 Element = Result.get();
489
490 // Make sure that we have an Objective-C pointer type or block.
491 if (!Element->getType()->isObjCObjectPointerType() &&
492 !Element->getType()->isBlockPointerType()) {
493 bool Recovered = false;
494
495 // If this is potentially an Objective-C numeric literal, add the '@'.
496 if (isa<IntegerLiteral>(OrigElement) ||
497 isa<CharacterLiteral>(OrigElement) ||
498 isa<FloatingLiteral>(OrigElement) ||
499 isa<ObjCBoolLiteralExpr>(OrigElement) ||
500 isa<CXXBoolLiteralExpr>(OrigElement)) {
501 if (S.ObjC().NSAPIObj->getNSNumberFactoryMethodKind(
502 OrigElement->getType())) {
503 int Which = isa<CharacterLiteral>(OrigElement) ? 1
504 : (isa<CXXBoolLiteralExpr>(OrigElement) ||
505 isa<ObjCBoolLiteralExpr>(OrigElement)) ? 2
506 : 3;
507
508 S.Diag(OrigElement->getBeginLoc(), diag::err_box_literal_collection)
509 << Which << OrigElement->getSourceRange()
510 << FixItHint::CreateInsertion(OrigElement->getBeginLoc(), "@");
511
512 Result = S.ObjC().BuildObjCNumericLiteral(OrigElement->getBeginLoc(),
513 OrigElement);
514 if (Result.isInvalid())
515 return ExprError();
516
517 Element = Result.get();
518 Recovered = true;
519 }
520 }
521 // If this is potentially an Objective-C string literal, add the '@'.
522 else if (StringLiteral *String = dyn_cast<StringLiteral>(OrigElement)) {
523 if (String->isOrdinary()) {
524 S.Diag(OrigElement->getBeginLoc(), diag::err_box_literal_collection)
525 << 0 << OrigElement->getSourceRange()
526 << FixItHint::CreateInsertion(OrigElement->getBeginLoc(), "@");
527
528 Result =
529 S.ObjC().BuildObjCStringLiteral(OrigElement->getBeginLoc(), String);
530 if (Result.isInvalid())
531 return ExprError();
532
533 Element = Result.get();
534 Recovered = true;
535 }
536 }
537
538 if (!Recovered) {
539 S.Diag(Element->getBeginLoc(), diag::err_invalid_collection_element)
540 << Element->getType();
541 return ExprError();
542 }
543 }
544 if (ArrayLiteral)
545 if (ObjCStringLiteral *getString =
546 dyn_cast<ObjCStringLiteral>(OrigElement)) {
547 if (StringLiteral *SL = getString->getString()) {
548 unsigned numConcat = SL->getNumConcatenated();
549 if (numConcat > 1) {
550 // Only warn if the concatenated string doesn't come from a macro.
551 bool hasMacro = false;
552 for (unsigned i = 0; i < numConcat ; ++i)
553 if (SL->getStrTokenLoc(i).isMacroID()) {
554 hasMacro = true;
555 break;
556 }
557 if (!hasMacro)
558 S.Diag(Element->getBeginLoc(),
559 diag::warn_concatenated_nsarray_literal)
560 << Element->getType();
561 }
562 }
563 }
564
565 // Make sure that the element has the type that the container factory
566 // function expects.
569 /*Consumed=*/false),
570 Element->getBeginLoc(), Element);
571}
572
574 ASTContext &Context = getASTContext();
575 if (ValueExpr->isTypeDependent()) {
576 ObjCBoxedExpr *BoxedExpr = new (Context)
577 ObjCBoxedExpr(ValueExpr, Context.DependentTy, nullptr,
578 /*ExpressibleAsConstantInitializer=*/true, SR);
579 return BoxedExpr;
580 }
581 ObjCMethodDecl *BoxingMethod = nullptr;
582 QualType BoxedType;
583 // Convert the expression to an RValue, so we can check for pointer types...
584 ExprResult RValue = SemaRef.DefaultFunctionArrayLvalueConversion(ValueExpr);
585 if (RValue.isInvalid()) {
586 return ExprError();
587 }
588
589 // Check if the runtime supports constant init literals
590 const bool IsConstInitLiteral =
592 SourceLocation Loc = SR.getBegin();
593 ValueExpr = RValue.get();
594 QualType ValueType(ValueExpr->getType());
595 if (const PointerType *PT = ValueType->getAs<PointerType>()) {
596 QualType PointeeType = PT->getPointeeType();
597 if (Context.hasSameUnqualifiedType(PointeeType, Context.CharTy)) {
598
599 if (!NSStringDecl) {
602 if (!NSStringDecl) {
603 return ExprError();
604 }
605 QualType NSStringObject = Context.getObjCInterfaceType(NSStringDecl);
606 NSStringPointer = Context.getObjCObjectPointerType(NSStringObject);
607 }
608
609 // The boxed expression can be emitted as a compile time constant if it is
610 // a string literal whose character encoding is compatible with UTF-8.
611 if (auto *CE = dyn_cast<ImplicitCastExpr>(ValueExpr))
612 if (CE->getCastKind() == CK_ArrayToPointerDecay)
613 if (auto *SL =
614 dyn_cast<StringLiteral>(CE->getSubExpr()->IgnoreParens())) {
615 assert((SL->isOrdinary() || SL->isUTF8()) &&
616 "unexpected character encoding");
617 StringRef Str = SL->getString();
618 const llvm::UTF8 *StrBegin = Str.bytes_begin();
619 const llvm::UTF8 *StrEnd = Str.bytes_end();
620 // Check that this is a valid UTF-8 string.
621 if (llvm::isLegalUTF8String(&StrBegin, StrEnd)) {
622 BoxedType = Context.getAttributedType(NullabilityKind::NonNull,
624 return new (Context)
625 ObjCBoxedExpr(CE, BoxedType, nullptr, true, SR);
626 }
627
628 Diag(SL->getBeginLoc(), diag::warn_objc_boxing_invalid_utf8_string)
629 << NSStringPointer << SL->getSourceRange();
630 }
631
633 IdentifierInfo *II = &Context.Idents.get("stringWithUTF8String");
634 Selector stringWithUTF8String = Context.Selectors.getUnarySelector(II);
635
636 // Look for the appropriate method within NSString.
637 BoxingMethod = NSStringDecl->lookupClassMethod(stringWithUTF8String);
638 if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) {
639 // Debugger needs to work even if NSString hasn't been defined.
640 TypeSourceInfo *ReturnTInfo = nullptr;
642 Context, SourceLocation(), SourceLocation(), stringWithUTF8String,
643 NSStringPointer, ReturnTInfo, NSStringDecl,
644 /*isInstance=*/false, /*isVariadic=*/false,
645 /*isPropertyAccessor=*/false,
646 /*isSynthesizedAccessorStub=*/false,
647 /*isImplicitlyDeclared=*/true,
648 /*isDefined=*/false, ObjCImplementationControl::Required,
649 /*HasRelatedResultType=*/false);
650 QualType ConstCharType = Context.CharTy.withConst();
651 ParmVarDecl *value =
652 ParmVarDecl::Create(Context, M,
654 &Context.Idents.get("value"),
655 Context.getPointerType(ConstCharType),
656 /*TInfo=*/nullptr,
657 SC_None, nullptr);
658 M->setMethodParams(Context, value, {});
659 BoxingMethod = M;
660 }
661
663 stringWithUTF8String, BoxingMethod))
664 return ExprError();
665
666 StringWithUTF8StringMethod = BoxingMethod;
667 }
668
669 BoxingMethod = StringWithUTF8StringMethod;
670 BoxedType = NSStringPointer;
671 // Transfer the nullability from method's return type.
672 std::optional<NullabilityKind> Nullability =
673 BoxingMethod->getReturnType()->getNullability();
674 if (Nullability)
675 BoxedType =
676 Context.getAttributedType(*Nullability, BoxedType, BoxedType);
677 }
678 } else if (ValueType->isBuiltinType()) {
679 // The other types we support are numeric, char and BOOL/bool. We could also
680 // provide limited support for structure types, such as NSRange, NSRect, and
681 // NSSize. See NSValue (NSValueGeometryExtensions) in <Foundation/NSGeometry.h>
682 // for more details.
683
684 // Check for a top-level character literal.
685 if (const CharacterLiteral *Char =
686 dyn_cast<CharacterLiteral>(ValueExpr->IgnoreParens())) {
687 // In C, character literals have type 'int'. That's not the type we want
688 // to use to determine the Objective-c literal kind.
689 switch (Char->getKind()) {
692 ValueType = Context.CharTy;
693 break;
694
696 ValueType = Context.getWideCharType();
697 break;
698
700 ValueType = Context.Char16Ty;
701 break;
702
704 ValueType = Context.Char32Ty;
705 break;
706 }
707 }
708 // Look for the appropriate method within NSNumber.
709 BoxingMethod = getNSNumberFactoryMethod(*this, Loc, ValueType);
710 BoxedType = NSNumberPointer;
711 } else if (const auto *ED = ValueType->getAsEnumDecl()) {
712 if (!ED->isComplete()) {
713 Diag(Loc, diag::err_objc_incomplete_boxed_expression_type)
714 << ValueType << ValueExpr->getSourceRange();
715 return ExprError();
716 }
717
718 BoxingMethod = getNSNumberFactoryMethod(*this, Loc, ED->getIntegerType());
719 BoxedType = NSNumberPointer;
720 } else if (ValueType->isObjCBoxableRecordType()) {
721 // Support for structure types, that marked as objc_boxable
722 // struct __attribute__((objc_boxable)) s { ... };
723
724 // Look up the NSValue class, if we haven't done so already. It's cached
725 // in the Sema instance.
726 if (!NSValueDecl) {
728 if (!NSValueDecl) {
729 return ExprError();
730 }
731
732 // generate the pointer to NSValue type.
733 QualType NSValueObject = Context.getObjCInterfaceType(NSValueDecl);
734 NSValuePointer = Context.getObjCObjectPointerType(NSValueObject);
735 }
736
738 const IdentifierInfo *II[] = {&Context.Idents.get("valueWithBytes"),
739 &Context.Idents.get("objCType")};
740 Selector ValueWithBytesObjCType = Context.Selectors.getSelector(2, II);
741
742 // Look for the appropriate method within NSValue.
743 BoxingMethod = NSValueDecl->lookupClassMethod(ValueWithBytesObjCType);
744 if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) {
745 // Debugger needs to work even if NSValue hasn't been defined.
746 TypeSourceInfo *ReturnTInfo = nullptr;
748 Context, SourceLocation(), SourceLocation(), ValueWithBytesObjCType,
749 NSValuePointer, ReturnTInfo, NSValueDecl,
750 /*isInstance=*/false,
751 /*isVariadic=*/false,
752 /*isPropertyAccessor=*/false,
753 /*isSynthesizedAccessorStub=*/false,
754 /*isImplicitlyDeclared=*/true,
755 /*isDefined=*/false, ObjCImplementationControl::Required,
756 /*HasRelatedResultType=*/false);
757
759
761 ParmVarDecl::Create(Context, M,
763 &Context.Idents.get("bytes"),
764 Context.VoidPtrTy.withConst(),
765 /*TInfo=*/nullptr,
766 SC_None, nullptr);
767 Params.push_back(bytes);
768
769 QualType ConstCharType = Context.CharTy.withConst();
771 ParmVarDecl::Create(Context, M,
773 &Context.Idents.get("type"),
774 Context.getPointerType(ConstCharType),
775 /*TInfo=*/nullptr,
776 SC_None, nullptr);
777 Params.push_back(type);
778
779 M->setMethodParams(Context, Params, {});
780 BoxingMethod = M;
781 }
782
784 ValueWithBytesObjCType, BoxingMethod))
785 return ExprError();
786
787 ValueWithBytesObjCTypeMethod = BoxingMethod;
788 }
789
790 if (!ValueType.isTriviallyCopyableType(Context)) {
791 Diag(Loc, diag::err_objc_non_trivially_copyable_boxed_expression_type)
792 << ValueType << ValueExpr->getSourceRange();
793 return ExprError();
794 }
795
796 BoxingMethod = ValueWithBytesObjCTypeMethod;
797 BoxedType = NSValuePointer;
798 }
799
800 if (!BoxingMethod) {
801 Diag(Loc, diag::err_objc_illegal_boxed_expression_type)
802 << ValueType << ValueExpr->getSourceRange();
803 return ExprError();
804 }
805
806 SemaRef.DiagnoseUseOfDecl(BoxingMethod, Loc);
807
808 ExprResult ConvertedValueExpr;
809 if (ValueType->isObjCBoxableRecordType()) {
811 ConvertedValueExpr = SemaRef.PerformCopyInitialization(
812 IE, ValueExpr->getExprLoc(), ValueExpr);
813 if (ConvertedValueExpr.isInvalid())
814 return ExprError();
815
816 ValueExpr = ConvertedValueExpr.get();
817 } else if (BoxingMethod->parameters().size() > 0) {
818 // Convert the expression to the type that the parameter requires.
819 ParmVarDecl *ParamDecl = BoxingMethod->parameters()[0];
821 ParamDecl);
822 ConvertedValueExpr =
823 SemaRef.PerformCopyInitialization(IE, SourceLocation(), ValueExpr);
824 if (ConvertedValueExpr.isInvalid())
825 return ExprError();
826
827 ValueExpr = ConvertedValueExpr.get();
828 }
829
830 ObjCBoxedExpr *BoxedExpr = new (Context)
831 ObjCBoxedExpr(ValueExpr, BoxedType, BoxingMethod, IsConstInitLiteral, SR);
832
833 return SemaRef.MaybeBindToTemporary(BoxedExpr);
834}
835
836/// Build an ObjC subscript pseudo-object expression, given that
837/// that's supported by the runtime.
839 SourceLocation RB, Expr *BaseExpr, Expr *IndexExpr,
840 ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod) {
841 assert(!getLangOpts().isSubscriptPointerArithmetic());
842 ASTContext &Context = getASTContext();
843
844 // We can't get dependent types here; our callers should have
845 // filtered them out.
846 assert((!BaseExpr->isTypeDependent() && !IndexExpr->isTypeDependent()) &&
847 "base or index cannot have dependent type here");
848
849 // Filter out placeholders in the index. In theory, overloads could
850 // be preserved here, although that might not actually work correctly.
851 ExprResult Result = SemaRef.CheckPlaceholderExpr(IndexExpr);
852 if (Result.isInvalid())
853 return ExprError();
854 IndexExpr = Result.get();
855
856 // Perform lvalue-to-rvalue conversion on the base.
857 Result = SemaRef.DefaultLvalueConversion(BaseExpr);
858 if (Result.isInvalid())
859 return ExprError();
860 BaseExpr = Result.get();
861
862 // Build the pseudo-object expression.
863 return new (Context) ObjCSubscriptRefExpr(
864 BaseExpr, IndexExpr, Context.PseudoObjectTy, VK_LValue, OK_ObjCSubscript,
865 getterMethod, setterMethod, RB);
866}
867
869 MultiExprArg Elements) {
870 ASTContext &Context = getASTContext();
871 SourceLocation Loc = SR.getBegin();
872
873 if (!NSArrayDecl) {
876 if (!NSArrayDecl) {
877 return ExprError();
878 }
879 }
880
881 // Find the arrayWithObjects:count: method, if we haven't done so already.
882 QualType IdT = Context.getObjCIdType();
885 Sel = NSAPIObj->getNSArraySelector(NSAPI::NSArr_arrayWithObjectsCount);
886 ObjCMethodDecl *Method = NSArrayDecl->lookupClassMethod(Sel);
887 if (!Method && getLangOpts().DebuggerObjCLiteral) {
888 TypeSourceInfo *ReturnTInfo = nullptr;
890 Context, SourceLocation(), SourceLocation(), Sel, IdT, ReturnTInfo,
891 Context.getTranslationUnitDecl(), false /*Instance*/,
892 false /*isVariadic*/,
893 /*isPropertyAccessor=*/false, /*isSynthesizedAccessorStub=*/false,
894 /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
897 ParmVarDecl *objects = ParmVarDecl::Create(Context, Method,
900 &Context.Idents.get("objects"),
901 Context.getPointerType(IdT),
902 /*TInfo=*/nullptr,
903 SC_None, nullptr);
904 Params.push_back(objects);
905 ParmVarDecl *cnt = ParmVarDecl::Create(Context, Method,
908 &Context.Idents.get("cnt"),
909 Context.UnsignedLongTy,
910 /*TInfo=*/nullptr, SC_None,
911 nullptr);
912 Params.push_back(cnt);
913 Method->setMethodParams(Context, Params, {});
914 }
915
917 return ExprError();
918
919 // Dig out the type that all elements should be converted to.
920 QualType T = Method->parameters()[0]->getType();
921 const PointerType *PtrT = T->getAs<PointerType>();
922 if (!PtrT ||
923 !Context.hasSameUnqualifiedType(PtrT->getPointeeType(), IdT)) {
924 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
925 << Sel;
926 Diag(Method->parameters()[0]->getLocation(),
927 diag::note_objc_literal_method_param)
928 << 0 << T
929 << Context.getPointerType(IdT.withConst());
930 return ExprError();
931 }
932
933 // Check that the 'count' parameter is integral.
934 if (!Method->parameters()[1]->getType()->isIntegerType()) {
935 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
936 << Sel;
937 Diag(Method->parameters()[1]->getLocation(),
938 diag::note_objc_literal_method_param)
939 << 1
940 << Method->parameters()[1]->getType()
941 << "integral";
942 return ExprError();
943 }
944
945 // We've found a good +arrayWithObjects:count: method. Save it!
947 }
948
949 QualType ObjectsType = ArrayWithObjectsMethod->parameters()[0]->getType();
950 QualType RequiredType = ObjectsType->castAs<PointerType>()->getPointeeType();
951
952 const LangOptions &LangOpts = getLangOpts();
953
954 bool ExpressibleAsConstantInitLiteral = LangOpts.ConstantNSArrayLiterals;
955
956 // ExpressibleAsConstantInitLiteral isn't meaningful for dependent literals.
957 if (ExpressibleAsConstantInitLiteral &&
958 llvm::any_of(Elements,
959 [](Expr *Elem) { return Elem->isValueDependent(); }))
960 ExpressibleAsConstantInitLiteral = false;
961
962 // We can stil emit a constant empty array
963 if (LangOpts.ObjCConstantLiterals && Elements.size() == 0) {
964 assert(LangOpts.ObjCRuntime.hasConstantEmptyCollections() &&
965 "The current ABI doesn't support an empty constant NSArray "
966 "singleton!");
967 ExpressibleAsConstantInitLiteral = true;
968 }
969
970 // Check that each of the elements provided is valid in a collection literal,
971 // performing conversions as necessary.
972 Expr **ElementsBuffer = Elements.data();
973 for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
975 SemaRef, ElementsBuffer[I], RequiredType, true);
976 if (Converted.isInvalid())
977 return ExprError();
978
979 ElementsBuffer[I] = Converted.get();
980
981 // Only allow actual literals and not references to other constant literals
982 // to be in constant collections since they *could* be modified / reassigned
983 if (ExpressibleAsConstantInitLiteral &&
984 (!isa<ObjCObjectLiteral>(ElementsBuffer[I]->IgnoreImpCasts()) ||
985 !ElementsBuffer[I]->isConstantInitializer(Context, false)))
986 ExpressibleAsConstantInitLiteral = false;
987 }
988
989 QualType Ty
990 = Context.getObjCObjectPointerType(
991 Context.getObjCInterfaceType(NSArrayDecl));
992
993 auto *ArrayLiteral =
995 ExpressibleAsConstantInitLiteral, SR);
996
997 return SemaRef.MaybeBindToTemporary(ArrayLiteral);
998}
999
1000/// Check for duplicate keys in an ObjC dictionary literal. For instance:
1001/// NSDictionary *nd = @{ @"foo" : @"bar", @"foo" : @"baz" };
1002static void
1004 ObjCDictionaryLiteral *Literal) {
1005 if (Literal->isValueDependent() || Literal->isTypeDependent())
1006 return;
1007
1008 // NSNumber has quite relaxed equality semantics (for instance, @YES is
1009 // considered equal to @1.0). For now, ignore floating points and just do a
1010 // bit-width and sign agnostic integer compare.
1011 struct APSIntCompare {
1012 bool operator()(const llvm::APSInt &LHS, const llvm::APSInt &RHS) const {
1013 return llvm::APSInt::compareValues(LHS, RHS) < 0;
1014 }
1015 };
1016
1017 llvm::DenseMap<StringRef, SourceLocation> StringKeys;
1018 std::map<llvm::APSInt, SourceLocation, APSIntCompare> IntegralKeys;
1019
1020 auto checkOneKey = [&](auto &Map, const auto &Key, SourceLocation Loc) {
1021 auto Pair = Map.insert({Key, Loc});
1022 if (!Pair.second) {
1023 S.Diag(Loc, diag::warn_nsdictionary_duplicate_key);
1024 S.Diag(Pair.first->second, diag::note_nsdictionary_duplicate_key_here);
1025 }
1026 };
1027
1028 for (unsigned Idx = 0, End = Literal->getNumElements(); Idx != End; ++Idx) {
1029 Expr *Key = Literal->getKeyValueElement(Idx).Key->IgnoreParenImpCasts();
1030
1031 if (auto *StrLit = dyn_cast<ObjCStringLiteral>(Key)) {
1032 StringRef Bytes = StrLit->getString()->getBytes();
1033 SourceLocation Loc = StrLit->getExprLoc();
1034 checkOneKey(StringKeys, Bytes, Loc);
1035 }
1036
1037 if (auto *BE = dyn_cast<ObjCBoxedExpr>(Key)) {
1038 Expr *Boxed = BE->getSubExpr();
1039 SourceLocation Loc = BE->getExprLoc();
1040
1041 // Check for @("foo").
1042 if (auto *Str = dyn_cast<StringLiteral>(Boxed->IgnoreParenImpCasts())) {
1043 checkOneKey(StringKeys, Str->getBytes(), Loc);
1044 continue;
1045 }
1046
1047 Expr::EvalResult Result;
1048 if (Boxed->EvaluateAsInt(Result, S.getASTContext(),
1050 checkOneKey(IntegralKeys, Result.Val.getInt(), Loc);
1051 }
1052 }
1053 }
1054}
1055
1058 ASTContext &Context = getASTContext();
1059 SourceLocation Loc = SR.getBegin();
1060
1061 if (!NSDictionaryDecl) {
1064 if (!NSDictionaryDecl) {
1065 return ExprError();
1066 }
1067 }
1068
1069 // Find the dictionaryWithObjects:forKeys:count: method, if we haven't done
1070 // so already.
1071 QualType IdT = Context.getObjCIdType();
1073 Selector Sel = NSAPIObj->getNSDictionarySelector(
1075 ObjCMethodDecl *Method = NSDictionaryDecl->lookupClassMethod(Sel);
1076 if (!Method && getLangOpts().DebuggerObjCLiteral) {
1078 Context, SourceLocation(), SourceLocation(), Sel, IdT,
1079 nullptr /*TypeSourceInfo */, Context.getTranslationUnitDecl(),
1080 false /*Instance*/, false /*isVariadic*/,
1081 /*isPropertyAccessor=*/false,
1082 /*isSynthesizedAccessorStub=*/false,
1083 /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
1086 ParmVarDecl *objects = ParmVarDecl::Create(Context, Method,
1089 &Context.Idents.get("objects"),
1090 Context.getPointerType(IdT),
1091 /*TInfo=*/nullptr, SC_None,
1092 nullptr);
1093 Params.push_back(objects);
1094 ParmVarDecl *keys = ParmVarDecl::Create(Context, Method,
1097 &Context.Idents.get("keys"),
1098 Context.getPointerType(IdT),
1099 /*TInfo=*/nullptr, SC_None,
1100 nullptr);
1101 Params.push_back(keys);
1102 ParmVarDecl *cnt = ParmVarDecl::Create(Context, Method,
1105 &Context.Idents.get("cnt"),
1106 Context.UnsignedLongTy,
1107 /*TInfo=*/nullptr, SC_None,
1108 nullptr);
1109 Params.push_back(cnt);
1110 Method->setMethodParams(Context, Params, {});
1111 }
1112
1114 Method))
1115 return ExprError();
1116
1117 // Dig out the type that all values should be converted to.
1118 QualType ValueT = Method->parameters()[0]->getType();
1119 const PointerType *PtrValue = ValueT->getAs<PointerType>();
1120 if (!PtrValue ||
1121 !Context.hasSameUnqualifiedType(PtrValue->getPointeeType(), IdT)) {
1122 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1123 << Sel;
1124 Diag(Method->parameters()[0]->getLocation(),
1125 diag::note_objc_literal_method_param)
1126 << 0 << ValueT
1127 << Context.getPointerType(IdT.withConst());
1128 return ExprError();
1129 }
1130
1131 // Dig out the type that all keys should be converted to.
1132 QualType KeyT = Method->parameters()[1]->getType();
1133 const PointerType *PtrKey = KeyT->getAs<PointerType>();
1134 if (!PtrKey ||
1135 !Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),
1136 IdT)) {
1137 bool err = true;
1138 if (PtrKey) {
1139 if (QIDNSCopying.isNull()) {
1140 // key argument of selector is id<NSCopying>?
1141 if (ObjCProtocolDecl *NSCopyingPDecl =
1142 LookupProtocol(&Context.Idents.get("NSCopying"), SR.getBegin())) {
1143 ObjCProtocolDecl *PQ[] = {NSCopyingPDecl};
1144 QIDNSCopying = Context.getObjCObjectType(
1145 Context.ObjCBuiltinIdTy, {},
1146 llvm::ArrayRef((ObjCProtocolDecl **)PQ, 1), false);
1147 QIDNSCopying = Context.getObjCObjectPointerType(QIDNSCopying);
1148 }
1149 }
1150 if (!QIDNSCopying.isNull())
1151 err = !Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),
1152 QIDNSCopying);
1153 }
1154
1155 if (err) {
1156 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1157 << Sel;
1158 Diag(Method->parameters()[1]->getLocation(),
1159 diag::note_objc_literal_method_param)
1160 << 1 << KeyT
1161 << Context.getPointerType(IdT.withConst());
1162 return ExprError();
1163 }
1164 }
1165
1166 // Check that the 'count' parameter is integral.
1167 QualType CountType = Method->parameters()[2]->getType();
1168 if (!CountType->isIntegerType()) {
1169 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1170 << Sel;
1171 Diag(Method->parameters()[2]->getLocation(),
1172 diag::note_objc_literal_method_param)
1173 << 2 << CountType
1174 << "integral";
1175 return ExprError();
1176 }
1177
1178 // We've found a good +dictionaryWithObjects:keys:count: method; save it!
1180 }
1181
1182 QualType ValuesT = DictionaryWithObjectsMethod->parameters()[0]->getType();
1183 QualType ValueT = ValuesT->castAs<PointerType>()->getPointeeType();
1184 QualType KeysT = DictionaryWithObjectsMethod->parameters()[1]->getType();
1185 QualType KeyT = KeysT->castAs<PointerType>()->getPointeeType();
1186
1187 // Check that each of the keys and values provided is valid in a collection
1188 // literal, performing conversions as necessary.
1189 bool HasPackExpansions = false;
1190
1191 const LangOptions &LangOpts = getLangOpts();
1192
1193 bool ExpressibleAsConstantInitLiteral = LangOpts.ConstantNSDictionaryLiterals;
1194
1195 // ExpressibleAsConstantInitLiteral isn't meaningful for dependent dictionary
1196 // literals.
1197 for (ObjCDictionaryElement &Elem : Elements) {
1198 if (!ExpressibleAsConstantInitLiteral)
1199 break;
1200 if (Elem.Key->isValueDependent() || Elem.Value->isValueDependent())
1201 ExpressibleAsConstantInitLiteral = false;
1202 }
1203
1204 // We can stil emit a constant empty dictionary.
1205 if (LangOpts.ObjCConstantLiterals && Elements.size() == 0) {
1206 assert(LangOpts.ObjCRuntime.hasConstantEmptyCollections() &&
1207 "The current ABI doesn't support an empty constant NSDictionary "
1208 "singleton!");
1209 ExpressibleAsConstantInitLiteral = true;
1210 }
1211
1212 for (ObjCDictionaryElement &Element : Elements) {
1213 // Check the key.
1214 ExprResult Key =
1215 CheckObjCCollectionLiteralElement(SemaRef, Element.Key, KeyT);
1216 if (Key.isInvalid())
1217 return ExprError();
1218
1219 // Check the value.
1221 CheckObjCCollectionLiteralElement(SemaRef, Element.Value, ValueT);
1222 if (Value.isInvalid())
1223 return ExprError();
1224
1225 Element.Key = Key.get();
1226 Element.Value = Value.get();
1227
1228 if (ExpressibleAsConstantInitLiteral &&
1229 !Element.Key->isConstantInitializer(Context, false))
1230 ExpressibleAsConstantInitLiteral = false;
1231
1232 // Only support string keys like plists
1233 if (ExpressibleAsConstantInitLiteral &&
1234 !isa<ObjCStringLiteral>(Element.Key->IgnoreImpCasts()))
1235 ExpressibleAsConstantInitLiteral = false;
1236
1237 // Only allow actual literals and not references to other constant literals
1238 // to be in constant collections since they *could* be modified / reassigned
1239 if (ExpressibleAsConstantInitLiteral &&
1240 (!isa<ObjCObjectLiteral>(Element.Value->IgnoreImpCasts()) ||
1241 !Element.Value->isConstantInitializer(Context, false)))
1242 ExpressibleAsConstantInitLiteral = false;
1243
1244 if (Element.EllipsisLoc.isInvalid())
1245 continue;
1246
1247 if (!Element.Key->containsUnexpandedParameterPack() &&
1248 !Element.Value->containsUnexpandedParameterPack()) {
1249 Diag(Element.EllipsisLoc,
1250 diag::err_pack_expansion_without_parameter_packs)
1251 << SourceRange(Element.Key->getBeginLoc(),
1252 Element.Value->getEndLoc());
1253 return ExprError();
1254 }
1255
1256 HasPackExpansions = true;
1257 }
1258
1259 QualType Ty = Context.getObjCObjectPointerType(
1260 Context.getObjCInterfaceType(NSDictionaryDecl));
1261
1262 auto *DictionaryLiteral = ObjCDictionaryLiteral::Create(
1263 Context, Elements, HasPackExpansions, Ty, DictionaryWithObjectsMethod,
1264 ExpressibleAsConstantInitLiteral, SR);
1265
1267
1268 return SemaRef.MaybeBindToTemporary(DictionaryLiteral);
1269}
1270
1272 TypeSourceInfo *EncodedTypeInfo,
1273 SourceLocation RParenLoc) {
1274 ASTContext &Context = getASTContext();
1275 QualType EncodedType = EncodedTypeInfo->getType();
1276 QualType StrTy;
1277 if (EncodedType->isDependentType())
1278 StrTy = Context.DependentTy;
1279 else {
1280 if (!EncodedType->getAsArrayTypeUnsafe() && //// Incomplete array is handled.
1281 !EncodedType->isVoidType()) // void is handled too.
1282 if (SemaRef.RequireCompleteType(AtLoc, EncodedType,
1283 diag::err_incomplete_type_objc_at_encode,
1284 EncodedTypeInfo->getTypeLoc()))
1285 return ExprError();
1286
1287 std::string Str;
1288 QualType NotEncodedT;
1289 Context.getObjCEncodingForType(EncodedType, Str, nullptr, &NotEncodedT);
1290 if (!NotEncodedT.isNull())
1291 Diag(AtLoc, diag::warn_incomplete_encoded_type)
1292 << EncodedType << NotEncodedT;
1293
1294 // The type of @encode is the same as the type of the corresponding string,
1295 // which is an array type.
1296 StrTy = Context.getStringLiteralArrayType(Context.CharTy, Str.size());
1297 }
1298
1299 return new (Context) ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc);
1300}
1301
1303 SourceLocation EncodeLoc,
1304 SourceLocation LParenLoc,
1305 ParsedType ty,
1306 SourceLocation RParenLoc) {
1307 ASTContext &Context = getASTContext();
1308 // FIXME: Preserve type source info ?
1309 TypeSourceInfo *TInfo;
1310 QualType EncodedType = SemaRef.GetTypeFromParser(ty, &TInfo);
1311 if (!TInfo)
1312 TInfo = Context.getTrivialTypeSourceInfo(
1313 EncodedType, SemaRef.getLocForEndOfToken(LParenLoc));
1314
1315 return BuildObjCEncodeExpression(AtLoc, TInfo, RParenLoc);
1316}
1317
1319 SourceLocation AtLoc,
1320 SourceLocation LParenLoc,
1321 SourceLocation RParenLoc,
1322 ObjCMethodDecl *Method,
1323 ObjCMethodList &MethList) {
1324 ObjCMethodList *M = &MethList;
1325 bool Warned = false;
1326 for (M = M->getNext(); M; M=M->getNext()) {
1327 ObjCMethodDecl *MatchingMethodDecl = M->getMethod();
1328 if (MatchingMethodDecl == Method ||
1329 isa<ObjCImplDecl>(MatchingMethodDecl->getDeclContext()) ||
1330 MatchingMethodDecl->getSelector() != Method->getSelector())
1331 continue;
1332 if (!S.ObjC().MatchTwoMethodDeclarations(Method, MatchingMethodDecl,
1334 if (!Warned) {
1335 Warned = true;
1336 S.Diag(AtLoc, diag::warn_multiple_selectors)
1337 << Method->getSelector() << FixItHint::CreateInsertion(LParenLoc, "(")
1338 << FixItHint::CreateInsertion(RParenLoc, ")");
1339 S.Diag(Method->getLocation(), diag::note_method_declared_at)
1340 << Method->getDeclName();
1341 }
1342 S.Diag(MatchingMethodDecl->getLocation(), diag::note_method_declared_at)
1343 << MatchingMethodDecl->getDeclName();
1344 }
1345 }
1346 return Warned;
1347}
1348
1350 ObjCMethodDecl *Method,
1351 SourceLocation LParenLoc,
1352 SourceLocation RParenLoc,
1353 bool WarnMultipleSelectors) {
1354 if (!WarnMultipleSelectors ||
1355 S.Diags.isIgnored(diag::warn_multiple_selectors, SourceLocation()))
1356 return;
1357 bool Warned = false;
1358 for (SemaObjC::GlobalMethodPool::iterator b = S.ObjC().MethodPool.begin(),
1359 e = S.ObjC().MethodPool.end();
1360 b != e; b++) {
1361 // first, instance methods
1362 ObjCMethodList &InstMethList = b->second.first;
1363 if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,
1364 Method, InstMethList))
1365 Warned = true;
1366
1367 // second, class methods
1368 ObjCMethodList &ClsMethList = b->second.second;
1369 if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,
1370 Method, ClsMethList) || Warned)
1371 return;
1372 }
1373}
1374
1376 ObjCMethodList &MethList,
1377 bool &onlyDirect,
1378 bool &anyDirect) {
1379 (void)Sel;
1380 ObjCMethodList *M = &MethList;
1381 ObjCMethodDecl *DirectMethod = nullptr;
1382 for (; M; M = M->getNext()) {
1383 ObjCMethodDecl *Method = M->getMethod();
1384 if (!Method)
1385 continue;
1386 assert(Method->getSelector() == Sel && "Method with wrong selector in method list");
1387 if (Method->isDirectMethod()) {
1388 anyDirect = true;
1389 DirectMethod = Method;
1390 } else
1391 onlyDirect = false;
1392 }
1393
1394 return DirectMethod;
1395}
1396
1397// Search the global pool for (potentially) direct methods matching the given
1398// selector. If a non-direct method is found, set \param onlyDirect to false. If
1399// a direct method is found, set \param anyDirect to true. Returns a direct
1400// method, if any.
1402 bool &onlyDirect,
1403 bool &anyDirect) {
1404 auto Iter = S.ObjC().MethodPool.find(Sel);
1405 if (Iter == S.ObjC().MethodPool.end())
1406 return nullptr;
1407
1409 S, Sel, Iter->second.first, onlyDirect, anyDirect);
1411 S, Sel, Iter->second.second, onlyDirect, anyDirect);
1412
1413 return DirectInstance ? DirectInstance : DirectClass;
1414}
1415
1417 auto *CurMD = S.getCurMethodDecl();
1418 if (!CurMD)
1419 return nullptr;
1420 ObjCInterfaceDecl *IFace = CurMD->getClassInterface();
1421
1422 // The language enforce that only one direct method is present in a given
1423 // class, so we just need to find one method in the current class to know
1424 // whether Sel is potentially direct in this context.
1425 if (ObjCMethodDecl *MD = IFace->lookupMethod(Sel, /*isInstance=*/true))
1426 return MD;
1427 if (ObjCMethodDecl *MD = IFace->lookupPrivateMethod(Sel, /*Instance=*/true))
1428 return MD;
1429 if (ObjCMethodDecl *MD = IFace->lookupMethod(Sel, /*isInstance=*/false))
1430 return MD;
1431 if (ObjCMethodDecl *MD = IFace->lookupPrivateMethod(Sel, /*Instance=*/false))
1432 return MD;
1433
1434 return nullptr;
1435}
1436
1438 SourceLocation AtLoc,
1439 SourceLocation SelLoc,
1440 SourceLocation LParenLoc,
1441 SourceLocation RParenLoc,
1442 bool WarnMultipleSelectors) {
1443 ASTContext &Context = getASTContext();
1445 SourceRange(LParenLoc, RParenLoc));
1446 if (!Method)
1448 SourceRange(LParenLoc, RParenLoc));
1449 if (!Method) {
1450 if (const ObjCMethodDecl *OM = SelectorsForTypoCorrection(Sel)) {
1451 Selector MatchedSel = OM->getSelector();
1452 SourceRange SelectorRange(LParenLoc.getLocWithOffset(1),
1453 RParenLoc.getLocWithOffset(-1));
1454 Diag(SelLoc, diag::warn_undeclared_selector_with_typo)
1455 << Sel << MatchedSel
1456 << FixItHint::CreateReplacement(SelectorRange, MatchedSel.getAsString());
1457
1458 } else
1459 Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
1460 } else {
1461 DiagnoseMismatchedSelectors(SemaRef, AtLoc, Method, LParenLoc, RParenLoc,
1462 WarnMultipleSelectors);
1463
1464 bool onlyDirect = true;
1465 bool anyDirect = false;
1466 ObjCMethodDecl *GlobalDirectMethod =
1467 LookupDirectMethodInGlobalPool(SemaRef, Sel, onlyDirect, anyDirect);
1468
1469 if (onlyDirect) {
1470 Diag(AtLoc, diag::err_direct_selector_expression)
1471 << Method->getSelector();
1472 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
1473 << Method->getDeclName();
1474 } else if (anyDirect) {
1475 // If we saw any direct methods, see if we see a direct member of the
1476 // current class. If so, the @selector will likely be used to refer to
1477 // this direct method.
1478 ObjCMethodDecl *LikelyTargetMethod =
1480 if (LikelyTargetMethod && LikelyTargetMethod->isDirectMethod()) {
1481 Diag(AtLoc, diag::warn_potentially_direct_selector_expression) << Sel;
1482 Diag(LikelyTargetMethod->getLocation(),
1483 diag::note_direct_method_declared_at)
1484 << LikelyTargetMethod->getDeclName();
1485 } else if (!LikelyTargetMethod) {
1486 // Otherwise, emit the "strict" variant of this diagnostic, unless
1487 // LikelyTargetMethod is non-direct.
1488 Diag(AtLoc, diag::warn_strict_potentially_direct_selector_expression)
1489 << Sel;
1490 Diag(GlobalDirectMethod->getLocation(),
1491 diag::note_direct_method_declared_at)
1492 << GlobalDirectMethod->getDeclName();
1493 }
1494 }
1495 }
1496
1497 if (Method &&
1498 Method->getImplementationControl() !=
1500 !SemaRef.getSourceManager().isInSystemHeader(Method->getLocation()))
1501 ReferencedSelectors.insert(std::make_pair(Sel, AtLoc));
1502
1503 // In ARC, forbid the user from using @selector for
1504 // retain/release/autorelease/dealloc/retainCount.
1505 if (getLangOpts().ObjCAutoRefCount) {
1506 switch (Sel.getMethodFamily()) {
1507 case OMF_retain:
1508 case OMF_release:
1509 case OMF_autorelease:
1510 case OMF_retainCount:
1511 case OMF_dealloc:
1512 Diag(AtLoc, diag::err_arc_illegal_selector) <<
1513 Sel << SourceRange(LParenLoc, RParenLoc);
1514 break;
1515
1516 case OMF_None:
1517 case OMF_alloc:
1518 case OMF_copy:
1519 case OMF_finalize:
1520 case OMF_init:
1521 case OMF_mutableCopy:
1522 case OMF_new:
1523 case OMF_self:
1524 case OMF_initialize:
1526 break;
1527 }
1528 }
1529 QualType Ty = Context.getObjCSelType();
1530 return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);
1531}
1532
1534 SourceLocation AtLoc,
1535 SourceLocation ProtoLoc,
1536 SourceLocation LParenLoc,
1537 SourceLocation ProtoIdLoc,
1538 SourceLocation RParenLoc) {
1539 ASTContext &Context = getASTContext();
1540 ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId, ProtoIdLoc);
1541 if (!PDecl) {
1542 Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
1543 return true;
1544 }
1545 if (PDecl->isNonRuntimeProtocol())
1546 Diag(ProtoLoc, diag::err_objc_non_runtime_protocol_in_protocol_expr)
1547 << PDecl;
1548 if (!PDecl->hasDefinition()) {
1549 Diag(ProtoLoc, diag::err_atprotocol_protocol) << PDecl;
1550 Diag(PDecl->getLocation(), diag::note_entity_declared_at) << PDecl;
1551 } else {
1552 PDecl = PDecl->getDefinition();
1553 }
1554
1555 QualType Ty = Context.getObjCProtoType();
1556 if (Ty.isNull())
1557 return true;
1558 Ty = Context.getObjCObjectPointerType(Ty);
1559 return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, ProtoIdLoc, RParenLoc);
1560}
1561
1562/// Try to capture an implicit reference to 'self'.
1564 DeclContext *DC = SemaRef.getFunctionLevelDeclContext();
1565
1566 // If we're not in an ObjC method, error out. Note that, unlike the
1567 // C++ case, we don't require an instance method --- class methods
1568 // still have a 'self', and we really do still need to capture it!
1569 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(DC);
1570 if (!method)
1571 return nullptr;
1572
1573 SemaRef.tryCaptureVariable(method->getSelfDecl(), Loc);
1574
1575 return method;
1576}
1577
1579 QualType origType = T;
1580 if (auto nullability = AttributedType::stripOuterNullability(T)) {
1581 if (T == Context.getObjCInstanceType()) {
1582 return Context.getAttributedType(*nullability, Context.getObjCIdType(),
1583 Context.getObjCIdType());
1584 }
1585
1586 return origType;
1587 }
1588
1589 if (T == Context.getObjCInstanceType())
1590 return Context.getObjCIdType();
1591
1592 return origType;
1593}
1594
1595/// Determine the result type of a message send based on the receiver type,
1596/// method, and the kind of message send.
1597///
1598/// This is the "base" result type, which will still need to be adjusted
1599/// to account for nullability.
1601 QualType ReceiverType,
1602 ObjCMethodDecl *Method,
1603 bool isClassMessage,
1604 bool isSuperMessage) {
1605 assert(Method && "Must have a method");
1606 if (!Method->hasRelatedResultType())
1607 return Method->getSendResultType(ReceiverType);
1608
1609 ASTContext &Context = S.Context;
1610
1611 // Local function that transfers the nullability of the method's
1612 // result type to the returned result.
1613 auto transferNullability = [&](QualType type) -> QualType {
1614 // If the method's result type has nullability, extract it.
1615 if (auto nullability =
1616 Method->getSendResultType(ReceiverType)->getNullability()) {
1617 // Strip off any outer nullability sugar from the provided type.
1618 (void)AttributedType::stripOuterNullability(type);
1619
1620 // Form a new attributed type using the method result type's nullability.
1621 return Context.getAttributedType(*nullability, type, type);
1622 }
1623
1624 return type;
1625 };
1626
1627 // If a method has a related return type:
1628 // - if the method found is an instance method, but the message send
1629 // was a class message send, T is the declared return type of the method
1630 // found
1631 if (Method->isInstanceMethod() && isClassMessage)
1632 return stripObjCInstanceType(Context,
1633 Method->getSendResultType(ReceiverType));
1634
1635 // - if the receiver is super, T is a pointer to the class of the
1636 // enclosing method definition
1637 if (isSuperMessage) {
1638 if (ObjCMethodDecl *CurMethod = S.getCurMethodDecl())
1639 if (ObjCInterfaceDecl *Class = CurMethod->getClassInterface()) {
1640 return transferNullability(
1641 Context.getObjCObjectPointerType(
1642 Context.getObjCInterfaceType(Class)));
1643 }
1644 }
1645
1646 // - if the receiver is the name of a class U, T is a pointer to U
1647 if (ReceiverType->getAsObjCInterfaceType())
1648 return transferNullability(Context.getObjCObjectPointerType(ReceiverType));
1649 // - if the receiver is of type Class or qualified Class type,
1650 // T is the declared return type of the method.
1651 if (ReceiverType->isObjCClassType() ||
1652 ReceiverType->isObjCQualifiedClassType())
1653 return stripObjCInstanceType(Context,
1654 Method->getSendResultType(ReceiverType));
1655
1656 // - if the receiver is id, qualified id, Class, or qualified Class, T
1657 // is the receiver type, otherwise
1658 // - T is the type of the receiver expression.
1659 return transferNullability(ReceiverType);
1660}
1661
1663 QualType ReceiverType,
1665 bool isClassMessage,
1666 bool isSuperMessage) {
1667 ASTContext &Context = getASTContext();
1668 // Produce the result type.
1670 SemaRef, ReceiverType, Method, isClassMessage, isSuperMessage);
1671
1672 // If this is a class message, ignore the nullability of the receiver.
1673 if (isClassMessage) {
1674 // In a class method, class messages to 'self' that return instancetype can
1675 // be typed as the current class. We can safely do this in ARC because self
1676 // can't be reassigned, and we do it unsafely outside of ARC because in
1677 // practice people never reassign self in class methods and there's some
1678 // virtue in not being aggressively pedantic.
1679 if (Receiver && Receiver->isObjCSelfExpr()) {
1680 assert(ReceiverType->isObjCClassType() && "expected a Class self");
1681 QualType T = Method->getSendResultType(ReceiverType);
1682 AttributedType::stripOuterNullability(T);
1683 if (T == Context.getObjCInstanceType()) {
1686 cast<DeclRefExpr>(Receiver->IgnoreParenImpCasts())->getDecl())
1687 ->getDeclContext());
1688 assert(MD->isClassMethod() && "expected a class method");
1689 QualType NewResultType = Context.getObjCObjectPointerType(
1690 Context.getObjCInterfaceType(MD->getClassInterface()));
1691 if (auto Nullability = resultType->getNullability())
1692 NewResultType = Context.getAttributedType(*Nullability, NewResultType,
1693 NewResultType);
1694 return NewResultType;
1695 }
1696 }
1697 return resultType;
1698 }
1699
1700 // There is nothing left to do if the result type cannot have a nullability
1701 // specifier.
1702 if (!resultType->canHaveNullability())
1703 return resultType;
1704
1705 // Map the nullability of the result into a table index.
1706 unsigned receiverNullabilityIdx = 0;
1707 if (std::optional<NullabilityKind> nullability =
1708 ReceiverType->getNullability()) {
1709 if (*nullability == NullabilityKind::NullableResult)
1710 nullability = NullabilityKind::Nullable;
1711 receiverNullabilityIdx = 1 + static_cast<unsigned>(*nullability);
1712 }
1713
1714 unsigned resultNullabilityIdx = 0;
1715 if (std::optional<NullabilityKind> nullability =
1716 resultType->getNullability()) {
1717 if (*nullability == NullabilityKind::NullableResult)
1718 nullability = NullabilityKind::Nullable;
1719 resultNullabilityIdx = 1 + static_cast<unsigned>(*nullability);
1720 }
1721
1722 // The table of nullability mappings, indexed by the receiver's nullability
1723 // and then the result type's nullability.
1724 static const uint8_t None = 0;
1725 static const uint8_t NonNull = 1;
1726 static const uint8_t Nullable = 2;
1727 static const uint8_t Unspecified = 3;
1728 static const uint8_t nullabilityMap[4][4] = {
1729 // None NonNull Nullable Unspecified
1730 /* None */ { None, None, Nullable, None },
1731 /* NonNull */ { None, NonNull, Nullable, Unspecified },
1732 /* Nullable */ { Nullable, Nullable, Nullable, Nullable },
1733 /* Unspecified */ { None, Unspecified, Nullable, Unspecified }
1734 };
1735
1736 unsigned newResultNullabilityIdx
1737 = nullabilityMap[receiverNullabilityIdx][resultNullabilityIdx];
1738 if (newResultNullabilityIdx == resultNullabilityIdx)
1739 return resultType;
1740
1741 // Strip off the existing nullability. This removes as little type sugar as
1742 // possible.
1743 do {
1744 if (auto attributed = dyn_cast<AttributedType>(resultType.getTypePtr())) {
1745 resultType = attributed->getModifiedType();
1746 } else {
1747 resultType = resultType.getDesugaredType(Context);
1748 }
1749 } while (resultType->getNullability());
1750
1751 // Add nullability back if needed.
1752 if (newResultNullabilityIdx > 0) {
1753 auto newNullability
1754 = static_cast<NullabilityKind>(newResultNullabilityIdx-1);
1755 return Context.getAttributedType(newNullability, resultType, resultType);
1756 }
1757
1758 return resultType;
1759}
1760
1761/// Look for an ObjC method whose result type exactly matches the given type.
1762static const ObjCMethodDecl *
1764 QualType instancetype) {
1765 if (MD->getReturnType() == instancetype)
1766 return MD;
1767
1768 // For these purposes, a method in an @implementation overrides a
1769 // declaration in the @interface.
1770 if (const ObjCImplDecl *impl =
1771 dyn_cast<ObjCImplDecl>(MD->getDeclContext())) {
1772 const ObjCContainerDecl *iface;
1773 if (const ObjCCategoryImplDecl *catImpl =
1774 dyn_cast<ObjCCategoryImplDecl>(impl)) {
1775 iface = catImpl->getCategoryDecl();
1776 } else {
1777 iface = impl->getClassInterface();
1778 }
1779
1780 const ObjCMethodDecl *ifaceMD =
1781 iface->getMethod(MD->getSelector(), MD->isInstanceMethod());
1782 if (ifaceMD) return findExplicitInstancetypeDeclarer(ifaceMD, instancetype);
1783 }
1784
1786 MD->getOverriddenMethods(overrides);
1787 for (unsigned i = 0, e = overrides.size(); i != e; ++i) {
1788 if (const ObjCMethodDecl *result =
1789 findExplicitInstancetypeDeclarer(overrides[i], instancetype))
1790 return result;
1791 }
1792
1793 return nullptr;
1794}
1795
1797 ASTContext &Context = getASTContext();
1798 // Only complain if we're in an ObjC method and the required return
1799 // type doesn't match the method's declared return type.
1800 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext);
1801 if (!MD || !MD->hasRelatedResultType() ||
1802 Context.hasSameUnqualifiedType(destType, MD->getReturnType()))
1803 return;
1804
1805 // Look for a method overridden by this method which explicitly uses
1806 // 'instancetype'.
1807 if (const ObjCMethodDecl *overridden =
1808 findExplicitInstancetypeDeclarer(MD, Context.getObjCInstanceType())) {
1809 SourceRange range = overridden->getReturnTypeSourceRange();
1810 SourceLocation loc = range.getBegin();
1811 if (loc.isInvalid())
1812 loc = overridden->getLocation();
1813 Diag(loc, diag::note_related_result_type_explicit)
1814 << /*current method*/ 1 << range;
1815 return;
1816 }
1817
1818 // Otherwise, if we have an interesting method family, note that.
1819 // This should always trigger if the above didn't.
1820 if (ObjCMethodFamily family = MD->getMethodFamily())
1821 Diag(MD->getLocation(), diag::note_related_result_type_family)
1822 << /*current method*/ 1
1823 << family;
1824}
1825
1827 ASTContext &Context = getASTContext();
1828 E = E->IgnoreParenImpCasts();
1829 const ObjCMessageExpr *MsgSend = dyn_cast<ObjCMessageExpr>(E);
1830 if (!MsgSend)
1831 return;
1832
1833 const ObjCMethodDecl *Method = MsgSend->getMethodDecl();
1834 if (!Method)
1835 return;
1836
1837 if (!Method->hasRelatedResultType())
1838 return;
1839
1840 if (Context.hasSameUnqualifiedType(
1841 Method->getReturnType().getNonReferenceType(), MsgSend->getType()))
1842 return;
1843
1844 if (!Context.hasSameUnqualifiedType(Method->getReturnType(),
1845 Context.getObjCInstanceType()))
1846 return;
1847
1848 Diag(Method->getLocation(), diag::note_related_result_type_inferred)
1849 << Method->isInstanceMethod() << Method->getSelector()
1850 << MsgSend->getType();
1851}
1852
1854 const Expr *Receiver, QualType ReceiverType, MultiExprArg Args,
1856 bool isClassMessage, bool isSuperMessage, SourceLocation lbrac,
1857 SourceLocation rbrac, SourceRange RecRange, QualType &ReturnType,
1858 ExprValueKind &VK) {
1859 ASTContext &Context = getASTContext();
1860 SourceLocation SelLoc;
1861 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
1862 SelLoc = SelectorLocs.front();
1863 else
1864 SelLoc = lbrac;
1865
1866 if (!Method) {
1867 // Apply default argument promotion as for (C99 6.5.2.2p6).
1868 for (unsigned i = 0, e = Args.size(); i != e; i++) {
1869 if (Args[i]->isTypeDependent())
1870 continue;
1871
1872 ExprResult result;
1873 if (getLangOpts().DebuggerSupport) {
1874 QualType paramTy; // ignored
1875 result = SemaRef.checkUnknownAnyArg(SelLoc, Args[i], paramTy);
1876 } else {
1877 result = SemaRef.DefaultArgumentPromotion(Args[i]);
1878 }
1879 if (result.isInvalid())
1880 return true;
1881 Args[i] = result.get();
1882 }
1883
1884 unsigned DiagID;
1885 if (getLangOpts().ObjCAutoRefCount)
1886 DiagID = diag::err_arc_method_not_found;
1887 else
1888 DiagID = isClassMessage ? diag::warn_class_method_not_found
1889 : diag::warn_inst_method_not_found;
1890 if (!getLangOpts().DebuggerSupport) {
1891 const ObjCMethodDecl *OMD = SelectorsForTypoCorrection(Sel, ReceiverType);
1892 if (OMD && !OMD->isInvalidDecl()) {
1893 if (getLangOpts().ObjCAutoRefCount)
1894 DiagID = diag::err_method_not_found_with_typo;
1895 else
1896 DiagID = isClassMessage ? diag::warn_class_method_not_found_with_typo
1897 : diag::warn_instance_method_not_found_with_typo;
1898 Selector MatchedSel = OMD->getSelector();
1899 SourceRange SelectorRange(SelectorLocs.front(), SelectorLocs.back());
1900 if (MatchedSel.isUnarySelector())
1901 Diag(SelLoc, DiagID)
1902 << Sel<< isClassMessage << MatchedSel
1903 << FixItHint::CreateReplacement(SelectorRange, MatchedSel.getAsString());
1904 else
1905 Diag(SelLoc, DiagID) << Sel<< isClassMessage << MatchedSel;
1906 }
1907 else
1908 Diag(SelLoc, DiagID)
1909 << Sel << isClassMessage << SourceRange(SelectorLocs.front(),
1910 SelectorLocs.back());
1911 // Find the class to which we are sending this message.
1912 if (auto *ObjPT = ReceiverType->getAs<ObjCObjectPointerType>()) {
1913 if (ObjCInterfaceDecl *ThisClass = ObjPT->getInterfaceDecl()) {
1914 Diag(ThisClass->getLocation(), diag::note_receiver_class_declared);
1915 if (!RecRange.isInvalid())
1916 if (ThisClass->lookupClassMethod(Sel))
1917 Diag(RecRange.getBegin(), diag::note_receiver_expr_here)
1918 << FixItHint::CreateReplacement(RecRange,
1919 ThisClass->getNameAsString());
1920 }
1921 }
1922 }
1923
1924 // In debuggers, we want to use __unknown_anytype for these
1925 // results so that clients can cast them.
1926 if (getLangOpts().DebuggerSupport) {
1927 ReturnType = Context.UnknownAnyTy;
1928 } else {
1929 ReturnType = Context.getObjCIdType();
1930 }
1931 VK = VK_PRValue;
1932 return false;
1933 }
1934
1935 ReturnType = getMessageSendResultType(Receiver, ReceiverType, Method,
1936 isClassMessage, isSuperMessage);
1937 VK = Expr::getValueKindForType(Method->getReturnType());
1938
1939 unsigned NumNamedArgs = Sel.getNumArgs();
1940 // Method might have more arguments than selector indicates. This is due
1941 // to addition of c-style arguments in method.
1942 if (Method->param_size() > Sel.getNumArgs())
1943 NumNamedArgs = Method->param_size();
1944 // FIXME. This need be cleaned up.
1945 if (Args.size() < NumNamedArgs) {
1946 Diag(SelLoc, diag::err_typecheck_call_too_few_args)
1947 << 2 << NumNamedArgs << static_cast<unsigned>(Args.size())
1948 << /*is non object*/ 0;
1949 return false;
1950 }
1951
1952 // Compute the set of type arguments to be substituted into each parameter
1953 // type.
1954 std::optional<ArrayRef<QualType>> typeArgs =
1955 ReceiverType->getObjCSubstitutions(Method->getDeclContext());
1956 bool IsError = false;
1957 for (unsigned i = 0; i < NumNamedArgs; i++) {
1958 // We can't do any type-checking on a type-dependent argument.
1959 if (Args[i]->isTypeDependent())
1960 continue;
1961
1962 Expr *argExpr = Args[i];
1963
1964 ParmVarDecl *param = Method->parameters()[i];
1965 assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
1966
1967 if (param->hasAttr<NoEscapeAttr>() &&
1968 param->getType()->isBlockPointerType())
1969 if (auto *BE = dyn_cast<BlockExpr>(
1970 argExpr->IgnoreParenNoopCasts(Context)))
1971 BE->getBlockDecl()->setDoesNotEscape();
1972
1973 // Strip the unbridged-cast placeholder expression off unless it's
1974 // a consumed argument.
1975 if (argExpr->hasPlaceholderType(BuiltinType::ARCUnbridgedCast) &&
1976 !param->hasAttr<CFConsumedAttr>())
1977 argExpr = stripARCUnbridgedCast(argExpr);
1978
1979 // If the parameter is __unknown_anytype, infer its type
1980 // from the argument.
1981 if (param->getType() == Context.UnknownAnyTy) {
1982 QualType paramType;
1983 ExprResult argE = SemaRef.checkUnknownAnyArg(SelLoc, argExpr, paramType);
1984 if (argE.isInvalid()) {
1985 IsError = true;
1986 } else {
1987 Args[i] = argE.get();
1988
1989 // Update the parameter type in-place.
1990 param->setType(paramType);
1991 }
1992 continue;
1993 }
1994
1995 QualType origParamType = param->getType();
1996 QualType paramType = param->getType();
1997 if (typeArgs)
1998 paramType = paramType.substObjCTypeArgs(
1999 Context,
2000 *typeArgs,
2002
2003 if (SemaRef.RequireCompleteType(
2004 argExpr->getSourceRange().getBegin(), paramType,
2005 diag::err_call_incomplete_argument, argExpr))
2006 return true;
2007
2008 InitializedEntity Entity
2009 = InitializedEntity::InitializeParameter(Context, param, paramType);
2010 ExprResult ArgE =
2011 SemaRef.PerformCopyInitialization(Entity, SourceLocation(), argExpr);
2012 if (ArgE.isInvalid())
2013 IsError = true;
2014 else {
2015 Args[i] = ArgE.getAs<Expr>();
2016
2017 // If we are type-erasing a block to a block-compatible
2018 // Objective-C pointer type, we may need to extend the lifetime
2019 // of the block object.
2020 if (typeArgs && Args[i]->isPRValue() && paramType->isBlockPointerType() &&
2021 Args[i]->getType()->isBlockPointerType() &&
2022 origParamType->isObjCObjectPointerType()) {
2023 ExprResult arg = Args[i];
2024 SemaRef.maybeExtendBlockObject(arg);
2025 Args[i] = arg.get();
2026 }
2027 }
2028 }
2029
2030 // Promote additional arguments to variadic methods.
2031 if (Method->isVariadic()) {
2032 for (unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) {
2033 if (Args[i]->isTypeDependent())
2034 continue;
2035
2036 ExprResult Arg = SemaRef.DefaultVariadicArgumentPromotion(
2037 Args[i], VariadicCallType::Method, nullptr);
2038 IsError |= Arg.isInvalid();
2039 Args[i] = Arg.get();
2040 }
2041 } else {
2042 // Check for extra arguments to non-variadic methods.
2043 if (Args.size() != NumNamedArgs) {
2044 Diag(Args[NumNamedArgs]->getBeginLoc(),
2045 diag::err_typecheck_call_too_many_args)
2046 << 2 /*method*/ << NumNamedArgs << static_cast<unsigned>(Args.size())
2047 << Method->getSourceRange() << /*is non object*/ 0
2048 << SourceRange(Args[NumNamedArgs]->getBeginLoc(),
2049 Args.back()->getEndLoc());
2050 }
2051 }
2052
2053 SemaRef.DiagnoseSentinelCalls(Method, SelLoc, Args);
2054
2055 // Do additional checkings on method.
2056 IsError |=
2057 CheckObjCMethodCall(Method, SelLoc, ArrayRef(Args.data(), Args.size()));
2058
2059 return IsError;
2060}
2061
2063 // 'self' is objc 'self' in an objc method only.
2064 ObjCMethodDecl *Method = dyn_cast_or_null<ObjCMethodDecl>(
2065 SemaRef.CurContext->getNonClosureAncestor());
2066 return isSelfExpr(RExpr, Method);
2067}
2068
2069bool SemaObjC::isSelfExpr(Expr *receiver, const ObjCMethodDecl *method) {
2070 if (!method) return false;
2071
2072 receiver = receiver->IgnoreParenLValueCasts();
2073 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(receiver))
2074 if (DRE->getDecl() == method->getSelfDecl())
2075 return true;
2076 return false;
2077}
2078
2079/// LookupMethodInType - Look up a method in an ObjCObjectType.
2081 bool isInstance) {
2082 const ObjCObjectType *objType = type->castAs<ObjCObjectType>();
2083 if (ObjCInterfaceDecl *iface = objType->getInterface()) {
2084 // Look it up in the main interface (and categories, etc.)
2085 if (ObjCMethodDecl *method = iface->lookupMethod(sel, isInstance))
2086 return method;
2087
2088 // Okay, look for "private" methods declared in any
2089 // @implementations we've seen.
2090 if (ObjCMethodDecl *method = iface->lookupPrivateMethod(sel, isInstance))
2091 return method;
2092 }
2093
2094 // Check qualifiers.
2095 for (const auto *I : objType->quals())
2096 if (ObjCMethodDecl *method = I->lookupMethod(sel, isInstance))
2097 return method;
2098
2099 return nullptr;
2100}
2101
2102/// LookupMethodInQualifiedType - Lookups up a method in protocol qualifier
2103/// list of a qualified objective pointer type.
2105 Selector Sel, const ObjCObjectPointerType *OPT, bool Instance) {
2106 ObjCMethodDecl *MD = nullptr;
2107 for (const auto *PROTO : OPT->quals()) {
2108 if ((MD = PROTO->lookupMethod(Sel, Instance))) {
2109 return MD;
2110 }
2111 }
2112 return nullptr;
2113}
2114
2115/// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an
2116/// objective C interface. This is a property reference expression.
2118 const ObjCObjectPointerType *OPT, Expr *BaseExpr, SourceLocation OpLoc,
2119 DeclarationName MemberName, SourceLocation MemberLoc,
2120 SourceLocation SuperLoc, QualType SuperType, bool Super) {
2121 ASTContext &Context = getASTContext();
2122 const ObjCInterfaceType *IFaceT = OPT->getInterfaceType();
2123 assert(IFaceT && "Expected an Interface");
2124 ObjCInterfaceDecl *IFace = IFaceT->getDecl();
2125
2126 if (!MemberName.isIdentifier()) {
2127 Diag(MemberLoc, diag::err_invalid_property_name)
2128 << MemberName << QualType(OPT, 0);
2129 return ExprError();
2130 }
2131
2133
2134 SourceRange BaseRange = Super? SourceRange(SuperLoc)
2135 : BaseExpr->getSourceRange();
2136 if (SemaRef.RequireCompleteType(MemberLoc, OPT->getPointeeType(),
2137 diag::err_property_not_found_forward_class,
2138 MemberName, BaseRange))
2139 return ExprError();
2140
2143 // Check whether we can reference this property.
2144 if (SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))
2145 return ExprError();
2146 if (Super)
2147 return new (Context)
2148 ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
2149 OK_ObjCProperty, MemberLoc, SuperLoc, SuperType);
2150 else
2151 return new (Context)
2152 ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
2153 OK_ObjCProperty, MemberLoc, BaseExpr);
2154 }
2155 // Check protocols on qualified interfaces.
2156 for (const auto *I : OPT->quals())
2157 if (ObjCPropertyDecl *PD = I->FindPropertyDeclaration(
2159 // Check whether we can reference this property.
2160 if (SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))
2161 return ExprError();
2162
2163 if (Super)
2164 return new (Context) ObjCPropertyRefExpr(
2165 PD, Context.PseudoObjectTy, VK_LValue, OK_ObjCProperty, MemberLoc,
2166 SuperLoc, SuperType);
2167 else
2168 return new (Context)
2169 ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
2170 OK_ObjCProperty, MemberLoc, BaseExpr);
2171 }
2172 // If that failed, look for an "implicit" property by seeing if the nullary
2173 // selector is implemented.
2174
2175 // FIXME: The logic for looking up nullary and unary selectors should be
2176 // shared with the code in ActOnInstanceMessage.
2177
2178 Selector Sel = SemaRef.PP.getSelectorTable().getNullarySelector(Member);
2179 ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
2180
2181 // May be found in property's qualified list.
2182 if (!Getter)
2183 Getter = LookupMethodInQualifiedType(Sel, OPT, true);
2184
2185 // If this reference is in an @implementation, check for 'private' methods.
2186 if (!Getter)
2187 Getter = IFace->lookupPrivateMethod(Sel);
2188
2189 if (Getter) {
2190 // Check if we can reference this property.
2191 if (SemaRef.DiagnoseUseOfDecl(Getter, MemberLoc))
2192 return ExprError();
2193 }
2194 // If we found a getter then this may be a valid dot-reference, we
2195 // will look for the matching setter, in case it is needed.
2197 SemaRef.PP.getIdentifierTable(), SemaRef.PP.getSelectorTable(), Member);
2198 ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
2199
2200 // May be found in property's qualified list.
2201 if (!Setter)
2202 Setter = LookupMethodInQualifiedType(SetterSel, OPT, true);
2203
2204 if (!Setter) {
2205 // If this reference is in an @implementation, also check for 'private'
2206 // methods.
2207 Setter = IFace->lookupPrivateMethod(SetterSel);
2208 }
2209
2210 if (Setter && SemaRef.DiagnoseUseOfDecl(Setter, MemberLoc))
2211 return ExprError();
2212
2213 // Special warning if member name used in a property-dot for a setter accessor
2214 // does not use a property with same name; e.g. obj.X = ... for a property with
2215 // name 'x'.
2216 if (Setter && Setter->isImplicit() && Setter->isPropertyAccessor() &&
2219 if (const ObjCPropertyDecl *PDecl = Setter->findPropertyDecl()) {
2220 // Do not warn if user is using property-dot syntax to make call to
2221 // user named setter.
2222 if (!(PDecl->getPropertyAttributes() &
2224 Diag(MemberLoc,
2225 diag::warn_property_access_suggest)
2226 << MemberName << QualType(OPT, 0) << PDecl->getName()
2227 << FixItHint::CreateReplacement(MemberLoc, PDecl->getName());
2228 }
2229 }
2230
2231 if (Getter || Setter) {
2232 if (Super)
2233 return new (Context)
2234 ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
2235 OK_ObjCProperty, MemberLoc, SuperLoc, SuperType);
2236 else
2237 return new (Context)
2238 ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
2239 OK_ObjCProperty, MemberLoc, BaseExpr);
2240
2241 }
2242
2243 // Attempt to correct for typos in property names.
2245 if (TypoCorrection Corrected = SemaRef.CorrectTypo(
2246 DeclarationNameInfo(MemberName, MemberLoc), Sema::LookupOrdinaryName,
2247 nullptr, nullptr, CCC, CorrectTypoKind::ErrorRecovery, IFace, false,
2248 OPT)) {
2249 DeclarationName TypoResult = Corrected.getCorrection();
2250 if (TypoResult.isIdentifier() &&
2251 TypoResult.getAsIdentifierInfo() == Member) {
2252 // There is no need to try the correction if it is the same.
2253 NamedDecl *ChosenDecl =
2254 Corrected.isKeyword() ? nullptr : Corrected.getFoundDecl();
2255 if (ChosenDecl && isa<ObjCPropertyDecl>(ChosenDecl))
2256 if (cast<ObjCPropertyDecl>(ChosenDecl)->isClassProperty()) {
2257 // This is a class property, we should not use the instance to
2258 // access it.
2259 Diag(MemberLoc, diag::err_class_property_found) << MemberName
2260 << OPT->getInterfaceDecl()->getName()
2262 OPT->getInterfaceDecl()->getName());
2263 return ExprError();
2264 }
2265 } else {
2266 SemaRef.diagnoseTypo(Corrected,
2267 PDiag(diag::err_property_not_found_suggest)
2268 << MemberName << QualType(OPT, 0));
2269 return HandleExprPropertyRefExpr(OPT, BaseExpr, OpLoc,
2270 TypoResult, MemberLoc,
2271 SuperLoc, SuperType, Super);
2272 }
2273 }
2274 ObjCInterfaceDecl *ClassDeclared;
2275 if (ObjCIvarDecl *Ivar =
2276 IFace->lookupInstanceVariable(Member, ClassDeclared)) {
2277 QualType T = Ivar->getType();
2278 if (const ObjCObjectPointerType * OBJPT =
2280 if (SemaRef.RequireCompleteType(MemberLoc, OBJPT->getPointeeType(),
2281 diag::err_property_not_as_forward_class,
2282 MemberName, BaseExpr))
2283 return ExprError();
2284 }
2285 Diag(MemberLoc,
2286 diag::err_ivar_access_using_property_syntax_suggest)
2287 << MemberName << QualType(OPT, 0) << Ivar->getDeclName()
2288 << FixItHint::CreateReplacement(OpLoc, "->");
2289 return ExprError();
2290 }
2291
2292 Diag(MemberLoc, diag::err_property_not_found)
2293 << MemberName << QualType(OPT, 0);
2294 if (Setter)
2295 Diag(Setter->getLocation(), diag::note_getter_unavailable)
2296 << MemberName << BaseExpr->getSourceRange();
2297 return ExprError();
2298}
2299
2301 const IdentifierInfo &receiverName, const IdentifierInfo &propertyName,
2302 SourceLocation receiverNameLoc, SourceLocation propertyNameLoc) {
2303 ASTContext &Context = getASTContext();
2304 const IdentifierInfo *receiverNamePtr = &receiverName;
2305 ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(receiverNamePtr,
2306 receiverNameLoc);
2307
2308 QualType SuperType;
2309 if (!IFace) {
2310 // If the "receiver" is 'super' in a method, handle it as an expression-like
2311 // property reference.
2312 if (receiverNamePtr->isStr("super")) {
2313 if (ObjCMethodDecl *CurMethod = tryCaptureObjCSelf(receiverNameLoc)) {
2314 if (auto classDecl = CurMethod->getClassInterface()) {
2315 SuperType = QualType(classDecl->getSuperClassType(), 0);
2316 if (CurMethod->isInstanceMethod()) {
2317 if (SuperType.isNull()) {
2318 // The current class does not have a superclass.
2319 Diag(receiverNameLoc, diag::err_root_class_cannot_use_super)
2320 << CurMethod->getClassInterface()->getIdentifier();
2321 return ExprError();
2322 }
2323 QualType T = Context.getObjCObjectPointerType(SuperType);
2324
2326 /*BaseExpr*/nullptr,
2327 SourceLocation()/*OpLoc*/,
2328 &propertyName,
2329 propertyNameLoc,
2330 receiverNameLoc, T, true);
2331 }
2332
2333 // Otherwise, if this is a class method, try dispatching to our
2334 // superclass.
2335 IFace = CurMethod->getClassInterface()->getSuperClass();
2336 }
2337 }
2338 }
2339
2340 if (!IFace) {
2341 Diag(receiverNameLoc, diag::err_expected_either) << tok::identifier
2342 << tok::l_paren;
2343 return ExprError();
2344 }
2345 }
2346
2347 Selector GetterSel;
2348 Selector SetterSel;
2349 if (auto PD = IFace->FindPropertyDeclaration(
2351 GetterSel = PD->getGetterName();
2352 SetterSel = PD->getSetterName();
2353 } else {
2354 GetterSel = SemaRef.PP.getSelectorTable().getNullarySelector(&propertyName);
2356 SemaRef.PP.getIdentifierTable(), SemaRef.PP.getSelectorTable(),
2357 &propertyName);
2358 }
2359
2360 // Search for a declared property first.
2361 ObjCMethodDecl *Getter = IFace->lookupClassMethod(GetterSel);
2362
2363 // If this reference is in an @implementation, check for 'private' methods.
2364 if (!Getter)
2365 Getter = IFace->lookupPrivateClassMethod(GetterSel);
2366
2367 if (Getter) {
2368 // FIXME: refactor/share with ActOnMemberReference().
2369 // Check if we can reference this property.
2370 if (SemaRef.DiagnoseUseOfDecl(Getter, propertyNameLoc))
2371 return ExprError();
2372 }
2373
2374 // Look for the matching setter, in case it is needed.
2375 ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
2376 if (!Setter) {
2377 // If this reference is in an @implementation, also check for 'private'
2378 // methods.
2379 Setter = IFace->lookupPrivateClassMethod(SetterSel);
2380 }
2381 // Look through local category implementations associated with the class.
2382 if (!Setter)
2383 Setter = IFace->getCategoryClassMethod(SetterSel);
2384
2385 if (Setter && SemaRef.DiagnoseUseOfDecl(Setter, propertyNameLoc))
2386 return ExprError();
2387
2388 if (Getter || Setter) {
2389 if (!SuperType.isNull())
2390 return new (Context)
2391 ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
2392 OK_ObjCProperty, propertyNameLoc, receiverNameLoc,
2393 SuperType);
2394
2395 return new (Context) ObjCPropertyRefExpr(
2396 Getter, Setter, Context.PseudoObjectTy, VK_LValue, OK_ObjCProperty,
2397 propertyNameLoc, receiverNameLoc, IFace);
2398 }
2399 return ExprError(Diag(propertyNameLoc, diag::err_property_not_found)
2400 << &propertyName << Context.getObjCInterfaceType(IFace));
2401}
2402
2403namespace {
2404
2405class ObjCInterfaceOrSuperCCC final : public CorrectionCandidateCallback {
2406 public:
2407 ObjCInterfaceOrSuperCCC(ObjCMethodDecl *Method) {
2408 // Determine whether "super" is acceptable in the current context.
2409 if (Method && Method->getClassInterface())
2410 WantObjCSuper = Method->getClassInterface()->getSuperClass();
2411 }
2412
2413 bool ValidateCandidate(const TypoCorrection &candidate) override {
2414 return candidate.getCorrectionDeclAs<ObjCInterfaceDecl>() ||
2415 candidate.isKeyword("super");
2416 }
2417
2418 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2419 return std::make_unique<ObjCInterfaceOrSuperCCC>(*this);
2420 }
2421};
2422
2423} // end anonymous namespace
2424
2427 SourceLocation NameLoc, bool IsSuper,
2428 bool HasTrailingDot, ParsedType &ReceiverType) {
2429 ASTContext &Context = getASTContext();
2430 ReceiverType = nullptr;
2431
2432 // If the identifier is "super" and there is no trailing dot, we're
2433 // messaging super. If the identifier is "super" and there is a
2434 // trailing dot, it's an instance message.
2435 if (IsSuper && S->isInObjcMethodScope())
2436 return HasTrailingDot? ObjCInstanceMessage : ObjCSuperMessage;
2437
2439 SemaRef.LookupName(Result, S);
2440
2441 switch (Result.getResultKind()) {
2443 // Normal name lookup didn't find anything. If we're in an
2444 // Objective-C method, look for ivars. If we find one, we're done!
2445 // FIXME: This is a hack. Ivar lookup should be part of normal
2446 // lookup.
2447 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
2448 if (!Method->getClassInterface()) {
2449 // Fall back: let the parser try to parse it as an instance message.
2450 return ObjCInstanceMessage;
2451 }
2452
2453 ObjCInterfaceDecl *ClassDeclared;
2454 if (Method->getClassInterface()->lookupInstanceVariable(Name,
2455 ClassDeclared))
2456 return ObjCInstanceMessage;
2457 }
2458
2459 // Break out; we'll perform typo correction below.
2460 break;
2461
2466 Result.suppressDiagnostics();
2467 return ObjCInstanceMessage;
2468
2470 // If the identifier is a class or not, and there is a trailing dot,
2471 // it's an instance message.
2472 if (HasTrailingDot)
2473 return ObjCInstanceMessage;
2474 // We found something. If it's a type, then we have a class
2475 // message. Otherwise, it's an instance message.
2476 NamedDecl *ND = Result.getFoundDecl();
2477 QualType T;
2478 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(ND))
2479 T = Context.getObjCInterfaceType(Class);
2480 else if (TypeDecl *Type = dyn_cast<TypeDecl>(ND)) {
2481 SemaRef.DiagnoseUseOfDecl(Type, NameLoc);
2482 T = Context.getTypeDeclType(ElaboratedTypeKeyword::None,
2483 /*Qualifier=*/std::nullopt, Type);
2484 } else
2485 return ObjCInstanceMessage;
2486
2487 // We have a class message, and T is the type we're
2488 // messaging. Build source-location information for it.
2489 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
2490 ReceiverType = SemaRef.CreateParsedType(T, TSInfo);
2491 return ObjCClassMessage;
2492 }
2493 }
2494
2495 ObjCInterfaceOrSuperCCC CCC(SemaRef.getCurMethodDecl());
2496 if (TypoCorrection Corrected = SemaRef.CorrectTypo(
2497 Result.getLookupNameInfo(), Result.getLookupKind(), S, nullptr, CCC,
2498 CorrectTypoKind::ErrorRecovery, nullptr, false, nullptr, false)) {
2499 if (Corrected.isKeyword()) {
2500 // If we've found the keyword "super" (the only keyword that would be
2501 // returned by CorrectTypo), this is a send to super.
2502 SemaRef.diagnoseTypo(Corrected, PDiag(diag::err_unknown_receiver_suggest)
2503 << Name);
2504 return ObjCSuperMessage;
2505 } else if (ObjCInterfaceDecl *Class =
2506 Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) {
2507 // If we found a declaration, correct when it refers to an Objective-C
2508 // class.
2509 SemaRef.diagnoseTypo(Corrected, PDiag(diag::err_unknown_receiver_suggest)
2510 << Name);
2511 QualType T = Context.getObjCInterfaceType(Class);
2512 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
2513 ReceiverType = SemaRef.CreateParsedType(T, TSInfo);
2514 return ObjCClassMessage;
2515 }
2516 }
2517
2518 // Fall back: let the parser try to parse it as an instance message.
2519 return ObjCInstanceMessage;
2520}
2521
2523 Selector Sel, SourceLocation LBracLoc,
2524 ArrayRef<SourceLocation> SelectorLocs,
2525 SourceLocation RBracLoc,
2526 MultiExprArg Args) {
2527 ASTContext &Context = getASTContext();
2528 // Determine whether we are inside a method or not.
2530 if (!Method) {
2531 Diag(SuperLoc, diag::err_invalid_receiver_to_message_super);
2532 return ExprError();
2533 }
2534
2535 ObjCInterfaceDecl *Class = Method->getClassInterface();
2536 if (!Class) {
2537 Diag(SuperLoc, diag::err_no_super_class_message)
2538 << Method->getDeclName();
2539 return ExprError();
2540 }
2541
2542 QualType SuperTy(Class->getSuperClassType(), 0);
2543 if (SuperTy.isNull()) {
2544 // The current class does not have a superclass.
2545 Diag(SuperLoc, diag::err_root_class_cannot_use_super)
2546 << Class->getIdentifier();
2547 return ExprError();
2548 }
2549
2550 // We are in a method whose class has a superclass, so 'super'
2551 // is acting as a keyword.
2552 if (Method->getSelector() == Sel)
2553 SemaRef.getCurFunction()->ObjCShouldCallSuper = false;
2554
2555 if (Method->isInstanceMethod()) {
2556 // Since we are in an instance method, this is an instance
2557 // message to the superclass instance.
2558 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2559 return BuildInstanceMessage(nullptr, SuperTy, SuperLoc,
2560 Sel, /*Method=*/nullptr,
2561 LBracLoc, SelectorLocs, RBracLoc, Args);
2562 }
2563
2564 // Since we are in a class method, this is a class message to
2565 // the superclass.
2566 return BuildClassMessage(/*ReceiverTypeInfo=*/nullptr,
2567 SuperTy,
2568 SuperLoc, Sel, /*Method=*/nullptr,
2569 LBracLoc, SelectorLocs, RBracLoc, Args);
2570}
2571
2573 bool isSuperReceiver,
2574 SourceLocation Loc, Selector Sel,
2576 MultiExprArg Args) {
2577 ASTContext &Context = getASTContext();
2578 TypeSourceInfo *receiverTypeInfo = nullptr;
2579 if (!ReceiverType.isNull())
2580 receiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType);
2581
2582 assert(((isSuperReceiver && Loc.isValid()) || receiverTypeInfo) &&
2583 "Either the super receiver location needs to be valid or the receiver "
2584 "needs valid type source information");
2585 return BuildClassMessage(receiverTypeInfo, ReceiverType,
2586 /*SuperLoc=*/isSuperReceiver ? Loc : SourceLocation(),
2587 Sel, Method, Loc, Loc, Loc, Args,
2588 /*isImplicit=*/true);
2589}
2590
2591static void applyCocoaAPICheck(Sema &S, const ObjCMessageExpr *Msg,
2592 unsigned DiagID,
2593 bool (*refactor)(const ObjCMessageExpr *,
2594 const NSAPI &, edit::Commit &)) {
2595 SourceLocation MsgLoc = Msg->getExprLoc();
2596 if (S.Diags.isIgnored(DiagID, MsgLoc))
2597 return;
2598
2600 edit::Commit ECommit(SM, S.LangOpts);
2601 if (refactor(Msg, *S.ObjC().NSAPIObj, ECommit)) {
2602 auto Builder = S.Diag(MsgLoc, DiagID)
2603 << Msg->getSelector() << Msg->getSourceRange();
2604 // FIXME: Don't emit diagnostic at all if fixits are non-commitable.
2605 if (!ECommit.isCommitable())
2606 return;
2608 I = ECommit.edit_begin(), E = ECommit.edit_end(); I != E; ++I) {
2609 const edit::Commit::Edit &Edit = *I;
2610 switch (Edit.Kind) {
2612 Builder.AddFixItHint(FixItHint::CreateInsertion(Edit.OrigLoc,
2613 Edit.Text,
2614 Edit.BeforePrev));
2615 break;
2617 Builder.AddFixItHint(
2619 Edit.getInsertFromRange(SM),
2620 Edit.BeforePrev));
2621 break;
2623 Builder.AddFixItHint(FixItHint::CreateRemoval(Edit.getFileRange(SM)));
2624 break;
2625 }
2626 }
2627 }
2628}
2629
2630static void checkCocoaAPI(Sema &S, const ObjCMessageExpr *Msg) {
2631 applyCocoaAPICheck(S, Msg, diag::warn_objc_redundant_literal_use,
2633}
2634
2636 const ObjCMethodDecl *Method,
2637 ArrayRef<Expr *> Args, QualType ReceiverType,
2638 bool IsClassObjectCall) {
2639 // Check if this is a performSelector method that uses a selector that returns
2640 // a record or a vector type.
2641 if (Method->getSelector().getMethodFamily() != OMF_performSelector ||
2642 Args.empty())
2643 return;
2644 const auto *SE = dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens());
2645 if (!SE)
2646 return;
2647 ObjCMethodDecl *ImpliedMethod;
2648 if (!IsClassObjectCall) {
2649 const auto *OPT = ReceiverType->getAs<ObjCObjectPointerType>();
2650 if (!OPT || !OPT->getInterfaceDecl())
2651 return;
2652 ImpliedMethod =
2653 OPT->getInterfaceDecl()->lookupInstanceMethod(SE->getSelector());
2654 if (!ImpliedMethod)
2655 ImpliedMethod =
2656 OPT->getInterfaceDecl()->lookupPrivateMethod(SE->getSelector());
2657 } else {
2658 const auto *IT = ReceiverType->getAs<ObjCInterfaceType>();
2659 if (!IT)
2660 return;
2661 ImpliedMethod = IT->getDecl()->lookupClassMethod(SE->getSelector());
2662 if (!ImpliedMethod)
2663 ImpliedMethod =
2664 IT->getDecl()->lookupPrivateClassMethod(SE->getSelector());
2665 }
2666 if (!ImpliedMethod)
2667 return;
2668 QualType Ret = ImpliedMethod->getReturnType();
2669 if (Ret->isRecordType() || Ret->isVectorType() || Ret->isExtVectorType()) {
2670 S.Diag(Loc, diag::warn_objc_unsafe_perform_selector)
2671 << Method->getSelector()
2672 << (!Ret->isRecordType()
2673 ? /*Vector*/ 2
2674 : Ret->isUnionType() ? /*Union*/ 1 : /*Struct*/ 0);
2675 S.Diag(ImpliedMethod->getBeginLoc(),
2676 diag::note_objc_unsafe_perform_selector_method_declared_here)
2677 << ImpliedMethod->getSelector() << Ret;
2678 }
2679}
2680
2681/// Diagnose use of %s directive in an NSString which is being passed
2682/// as formatting string to formatting method.
2683static void
2685 ObjCMethodDecl *Method,
2686 Selector Sel,
2687 Expr **Args, unsigned NumArgs) {
2688 unsigned Idx = 0;
2689 bool Format = false;
2691 if (SFFamily == ObjCStringFormatFamily::SFF_NSString) {
2692 Idx = 0;
2693 Format = true;
2694 }
2695 else if (Method) {
2696 for (const auto *I : Method->specific_attrs<FormatAttr>()) {
2697 if (S.ObjC().GetFormatNSStringIdx(I, Idx)) {
2698 Format = true;
2699 break;
2700 }
2701 }
2702 }
2703 if (!Format || NumArgs <= Idx)
2704 return;
2705
2706 Expr *FormatExpr = Args[Idx];
2707 if (ObjCStringLiteral *OSL =
2708 dyn_cast<ObjCStringLiteral>(FormatExpr->IgnoreParenImpCasts())) {
2709 StringLiteral *FormatString = OSL->getString();
2710 if (S.FormatStringHasSArg(FormatString)) {
2711 S.Diag(FormatExpr->getExprLoc(), diag::warn_objc_cdirective_format_string)
2712 << "%s" << 0 << 0;
2713 if (Method)
2714 S.Diag(Method->getLocation(), diag::note_method_declared_at)
2715 << Method->getDeclName();
2716 }
2717 }
2718}
2719
2720/// Build an Objective-C class message expression.
2721///
2722/// This routine takes care of both normal class messages and
2723/// class messages to the superclass.
2724///
2725/// \param ReceiverTypeInfo Type source information that describes the
2726/// receiver of this message. This may be NULL, in which case we are
2727/// sending to the superclass and \p SuperLoc must be a valid source
2728/// location.
2729
2730/// \param ReceiverType The type of the object receiving the
2731/// message. When \p ReceiverTypeInfo is non-NULL, this is the same
2732/// type as that refers to. For a superclass send, this is the type of
2733/// the superclass.
2734///
2735/// \param SuperLoc The location of the "super" keyword in a
2736/// superclass message.
2737///
2738/// \param Sel The selector to which the message is being sent.
2739///
2740/// \param Method The method that this class message is invoking, if
2741/// already known.
2742///
2743/// \param LBracLoc The location of the opening square bracket ']'.
2744///
2745/// \param RBracLoc The location of the closing square bracket ']'.
2746///
2747/// \param ArgsIn The message arguments.
2749 TypeSourceInfo *ReceiverTypeInfo, QualType ReceiverType,
2751 SourceLocation LBracLoc, ArrayRef<SourceLocation> SelectorLocs,
2752 SourceLocation RBracLoc, MultiExprArg ArgsIn, bool isImplicit) {
2753 ASTContext &Context = getASTContext();
2754 SourceLocation Loc = SuperLoc.isValid()? SuperLoc
2755 : ReceiverTypeInfo->getTypeLoc().getSourceRange().getBegin();
2756 if (LBracLoc.isInvalid()) {
2757 Diag(Loc, diag::err_missing_open_square_message_send)
2758 << FixItHint::CreateInsertion(Loc, "[");
2759 LBracLoc = Loc;
2760 }
2761 ArrayRef<SourceLocation> SelectorSlotLocs;
2762 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2763 SelectorSlotLocs = SelectorLocs;
2764 else
2765 SelectorSlotLocs = Loc;
2766 SourceLocation SelLoc = SelectorSlotLocs.front();
2767
2768 if (ReceiverType->isDependentType()) {
2769 // If the receiver type is dependent, we can't type-check anything
2770 // at this point. Build a dependent expression.
2771 unsigned NumArgs = ArgsIn.size();
2772 Expr **Args = ArgsIn.data();
2773 assert(SuperLoc.isInvalid() && "Message to super with dependent type");
2774 return ObjCMessageExpr::Create(Context, ReceiverType, VK_PRValue, LBracLoc,
2775 ReceiverTypeInfo, Sel, SelectorLocs,
2776 /*Method=*/nullptr, ArrayRef(Args, NumArgs),
2777 RBracLoc, isImplicit);
2778 }
2779
2780 // Find the class to which we are sending this message.
2781 ObjCInterfaceDecl *Class = nullptr;
2782 const ObjCObjectType *ClassType = ReceiverType->getAs<ObjCObjectType>();
2783 if (!ClassType || !(Class = ClassType->getInterface())) {
2784 Diag(Loc, diag::err_invalid_receiver_class_message)
2785 << ReceiverType;
2786 return ExprError();
2787 }
2788 assert(Class && "We don't know which class we're messaging?");
2789 // objc++ diagnoses during typename annotation.
2790 if (!getLangOpts().CPlusPlus)
2791 (void)SemaRef.DiagnoseUseOfDecl(Class, SelectorSlotLocs);
2792 // Find the method we are messaging.
2793 if (!Method) {
2794 SourceRange TypeRange
2795 = SuperLoc.isValid()? SourceRange(SuperLoc)
2796 : ReceiverTypeInfo->getTypeLoc().getSourceRange();
2797 if (SemaRef.RequireCompleteType(Loc, Context.getObjCInterfaceType(Class),
2798 (getLangOpts().ObjCAutoRefCount
2799 ? diag::err_arc_receiver_forward_class
2800 : diag::warn_receiver_forward_class),
2801 TypeRange)) {
2802 // A forward class used in messaging is treated as a 'Class'
2804 SourceRange(LBracLoc, RBracLoc));
2805 if (Method && !getLangOpts().ObjCAutoRefCount)
2806 Diag(Method->getLocation(), diag::note_method_sent_forward_class)
2807 << Method->getDeclName();
2808 }
2809 if (!Method)
2810 Method = Class->lookupClassMethod(Sel);
2811
2812 // If we have an implementation in scope, check "private" methods.
2813 if (!Method)
2814 Method = Class->lookupPrivateClassMethod(Sel);
2815
2816 if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, nullptr,
2817 false, false, Class))
2818 return ExprError();
2819 }
2820
2821 // Check the argument types and determine the result type.
2822 QualType ReturnType;
2824
2825 unsigned NumArgs = ArgsIn.size();
2826 Expr **Args = ArgsIn.data();
2827 if (CheckMessageArgumentTypes(/*Receiver=*/nullptr, ReceiverType,
2828 MultiExprArg(Args, NumArgs), Sel, SelectorLocs,
2829 Method, true, SuperLoc.isValid(), LBracLoc,
2830 RBracLoc, SourceRange(), ReturnType, VK))
2831 return ExprError();
2832
2833 if (Method && !Method->getReturnType()->isVoidType() &&
2834 SemaRef.RequireCompleteType(
2835 LBracLoc, Method->getReturnType(),
2836 diag::err_illegal_message_expr_incomplete_type))
2837 return ExprError();
2838
2839 if (Method && Method->isDirectMethod() && SuperLoc.isValid()) {
2840 Diag(SuperLoc, diag::err_messaging_super_with_direct_method)
2842 SuperLoc, getLangOpts().ObjCAutoRefCount
2843 ? "self"
2844 : Method->getClassInterface()->getName());
2845 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
2846 << Method->getDeclName();
2847 }
2848
2849 // Warn about explicit call of +initialize on its own class. But not on 'super'.
2850 if (Method && Method->getMethodFamily() == OMF_initialize) {
2851 if (!SuperLoc.isValid()) {
2852 const ObjCInterfaceDecl *ID =
2853 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext());
2854 if (ID == Class) {
2855 Diag(Loc, diag::warn_direct_initialize_call);
2856 Diag(Method->getLocation(), diag::note_method_declared_at)
2857 << Method->getDeclName();
2858 }
2859 } else if (ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl()) {
2860 // [super initialize] is allowed only within an +initialize implementation
2861 if (CurMeth->getMethodFamily() != OMF_initialize) {
2862 Diag(Loc, diag::warn_direct_super_initialize_call);
2863 Diag(Method->getLocation(), diag::note_method_declared_at)
2864 << Method->getDeclName();
2865 Diag(CurMeth->getLocation(), diag::note_method_declared_at)
2866 << CurMeth->getDeclName();
2867 }
2868 }
2869 }
2870
2872
2873 // Construct the appropriate ObjCMessageExpr.
2875 if (SuperLoc.isValid())
2877 Context, ReturnType, VK, LBracLoc, SuperLoc, /*IsInstanceSuper=*/false,
2878 ReceiverType, Sel, SelectorLocs, Method, ArrayRef(Args, NumArgs),
2879 RBracLoc, isImplicit);
2880 else {
2882 Context, ReturnType, VK, LBracLoc, ReceiverTypeInfo, Sel, SelectorLocs,
2883 Method, ArrayRef(Args, NumArgs), RBracLoc, isImplicit);
2884 if (!isImplicit)
2886 }
2887 if (Method)
2888 checkFoundationAPI(SemaRef, SelLoc, Method, ArrayRef(Args, NumArgs),
2889 ReceiverType, /*IsClassObjectCall=*/true);
2890 return SemaRef.MaybeBindToTemporary(Result);
2891}
2892
2893// ActOnClassMessage - used for both unary and keyword messages.
2894// ArgExprs is optional - if it is present, the number of expressions
2895// is obtained from Sel.getNumArgs().
2897 Selector Sel, SourceLocation LBracLoc,
2898 ArrayRef<SourceLocation> SelectorLocs,
2899 SourceLocation RBracLoc,
2900 MultiExprArg Args) {
2901 ASTContext &Context = getASTContext();
2902 TypeSourceInfo *ReceiverTypeInfo;
2903 QualType ReceiverType =
2904 SemaRef.GetTypeFromParser(Receiver, &ReceiverTypeInfo);
2905 if (ReceiverType.isNull())
2906 return ExprError();
2907
2908 if (!ReceiverTypeInfo)
2909 ReceiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType, LBracLoc);
2910
2911 return BuildClassMessage(ReceiverTypeInfo, ReceiverType,
2912 /*SuperLoc=*/SourceLocation(), Sel,
2913 /*Method=*/nullptr, LBracLoc, SelectorLocs, RBracLoc,
2914 Args);
2915}
2916
2918 Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel,
2920 return BuildInstanceMessage(Receiver, ReceiverType,
2921 /*SuperLoc=*/!Receiver ? Loc : SourceLocation(),
2922 Sel, Method, Loc, Loc, Loc, Args,
2923 /*isImplicit=*/true);
2924}
2925
2927 if (!S.ObjC().NSAPIObj)
2928 return false;
2929 const auto *Protocol = dyn_cast<ObjCProtocolDecl>(M->getDeclContext());
2930 if (!Protocol)
2931 return false;
2932 const IdentifierInfo *II =
2933 S.ObjC().NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject);
2934 if (const auto *RootClass = dyn_cast_or_null<ObjCInterfaceDecl>(
2935 S.LookupSingleName(S.TUScope, II, Protocol->getBeginLoc(),
2937 for (const ObjCProtocolDecl *P : RootClass->all_referenced_protocols()) {
2938 if (P->getCanonicalDecl() == Protocol->getCanonicalDecl())
2939 return true;
2940 }
2941 }
2942 return false;
2943}
2944
2945/// Build an Objective-C instance message expression.
2946///
2947/// This routine takes care of both normal instance messages and
2948/// instance messages to the superclass instance.
2949///
2950/// \param Receiver The expression that computes the object that will
2951/// receive this message. This may be empty, in which case we are
2952/// sending to the superclass instance and \p SuperLoc must be a valid
2953/// source location.
2954///
2955/// \param ReceiverType The (static) type of the object receiving the
2956/// message. When a \p Receiver expression is provided, this is the
2957/// same type as that expression. For a superclass instance send, this
2958/// is a pointer to the type of the superclass.
2959///
2960/// \param SuperLoc The location of the "super" keyword in a
2961/// superclass instance message.
2962///
2963/// \param Sel The selector to which the message is being sent.
2964///
2965/// \param Method The method that this instance message is invoking, if
2966/// already known.
2967///
2968/// \param LBracLoc The location of the opening square bracket ']'.
2969///
2970/// \param RBracLoc The location of the closing square bracket ']'.
2971///
2972/// \param ArgsIn The message arguments.
2974 Expr *Receiver, QualType ReceiverType, SourceLocation SuperLoc,
2976 ArrayRef<SourceLocation> SelectorLocs, SourceLocation RBracLoc,
2977 MultiExprArg ArgsIn, bool isImplicit) {
2978 assert((Receiver || SuperLoc.isValid()) && "If the Receiver is null, the "
2979 "SuperLoc must be valid so we can "
2980 "use it instead.");
2981 ASTContext &Context = getASTContext();
2982
2983 // The location of the receiver.
2984 SourceLocation Loc = SuperLoc.isValid() ? SuperLoc : Receiver->getBeginLoc();
2985 SourceRange RecRange =
2986 SuperLoc.isValid()? SuperLoc : Receiver->getSourceRange();
2987 ArrayRef<SourceLocation> SelectorSlotLocs;
2988 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2989 SelectorSlotLocs = SelectorLocs;
2990 else
2991 SelectorSlotLocs = Loc;
2992 SourceLocation SelLoc = SelectorSlotLocs.front();
2993
2994 if (LBracLoc.isInvalid()) {
2995 Diag(Loc, diag::err_missing_open_square_message_send)
2996 << FixItHint::CreateInsertion(Loc, "[");
2997 LBracLoc = Loc;
2998 }
2999
3000 // If we have a receiver expression, perform appropriate promotions
3001 // and determine receiver type.
3002 if (Receiver) {
3003 if (Receiver->hasPlaceholderType()) {
3005 if (Receiver->getType() == Context.UnknownAnyTy)
3006 Result =
3007 SemaRef.forceUnknownAnyToType(Receiver, Context.getObjCIdType());
3008 else
3009 Result = SemaRef.CheckPlaceholderExpr(Receiver);
3010 if (Result.isInvalid()) return ExprError();
3011 Receiver = Result.get();
3012 }
3013
3014 if (Receiver->isTypeDependent()) {
3015 // If the receiver is type-dependent, we can't type-check anything
3016 // at this point. Build a dependent expression.
3017 unsigned NumArgs = ArgsIn.size();
3018 Expr **Args = ArgsIn.data();
3019 assert(SuperLoc.isInvalid() && "Message to super with dependent type");
3021 Context, Context.DependentTy, VK_PRValue, LBracLoc, Receiver, Sel,
3022 SelectorLocs, /*Method=*/nullptr, ArrayRef(Args, NumArgs), RBracLoc,
3023 isImplicit);
3024 }
3025
3026 // If necessary, apply function/array conversion to the receiver.
3027 // C99 6.7.5.3p[7,8].
3028 ExprResult Result = SemaRef.DefaultFunctionArrayLvalueConversion(Receiver);
3029 if (Result.isInvalid())
3030 return ExprError();
3031 Receiver = Result.get();
3032 ReceiverType = Receiver->getType();
3033
3034 // If the receiver is an ObjC pointer, a block pointer, or an
3035 // __attribute__((NSObject)) pointer, we don't need to do any
3036 // special conversion in order to look up a receiver.
3037 if (ReceiverType->isObjCRetainableType()) {
3038 // do nothing
3039 } else if (!getLangOpts().ObjCAutoRefCount &&
3040 !Context.getObjCIdType().isNull() &&
3041 (ReceiverType->isPointerType() ||
3042 ReceiverType->isIntegerType())) {
3043 // Implicitly convert integers and pointers to 'id' but emit a warning.
3044 // But not in ARC.
3045 Diag(Loc, diag::warn_bad_receiver_type) << ReceiverType << RecRange;
3046 if (ReceiverType->isPointerType()) {
3047 Receiver = SemaRef
3048 .ImpCastExprToType(Receiver, Context.getObjCIdType(),
3049 CK_CPointerToObjCPointerCast)
3050 .get();
3051 } else {
3052 // TODO: specialized warning on null receivers?
3053 bool IsNull = Receiver->isNullPointerConstant(Context,
3055 CastKind Kind = IsNull ? CK_NullToPointer : CK_IntegralToPointer;
3056 Receiver =
3057 SemaRef.ImpCastExprToType(Receiver, Context.getObjCIdType(), Kind)
3058 .get();
3059 }
3060 ReceiverType = Receiver->getType();
3061 } else if (getLangOpts().CPlusPlus) {
3062 // The receiver must be a complete type.
3063 if (SemaRef.RequireCompleteType(Loc, Receiver->getType(),
3064 diag::err_incomplete_receiver_type))
3065 return ExprError();
3066
3067 ExprResult result =
3068 SemaRef.PerformContextuallyConvertToObjCPointer(Receiver);
3069 if (result.isUsable()) {
3070 Receiver = result.get();
3071 ReceiverType = Receiver->getType();
3072 }
3073 }
3074 }
3075
3076 // There's a somewhat weird interaction here where we assume that we
3077 // won't actually have a method unless we also don't need to do some
3078 // of the more detailed type-checking on the receiver.
3079
3080 if (!Method) {
3081 // Handle messages to id and __kindof types (where we use the
3082 // global method pool).
3083 const ObjCObjectType *typeBound = nullptr;
3084 bool receiverIsIdLike = ReceiverType->isObjCIdOrObjectKindOfType(Context,
3085 typeBound);
3086 if (receiverIsIdLike || ReceiverType->isBlockPointerType() ||
3087 (Receiver && Context.isObjCNSObjectType(Receiver->getType()))) {
3089 // If we have a type bound, further filter the methods.
3090 CollectMultipleMethodsInGlobalPool(Sel, Methods, true/*InstanceFirst*/,
3091 true/*CheckTheOther*/, typeBound);
3092 if (!Methods.empty()) {
3093 // We choose the first method as the initial candidate, then try to
3094 // select a better one.
3095 Method = Methods[0];
3096
3097 if (ObjCMethodDecl *BestMethod = SemaRef.SelectBestMethod(
3098 Sel, ArgsIn, Method->isInstanceMethod(), Methods))
3099 Method = BestMethod;
3100
3102 SourceRange(LBracLoc, RBracLoc),
3103 receiverIsIdLike, Methods))
3104 SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs);
3105 }
3106 } else if (ReceiverType->isObjCClassOrClassKindOfType() ||
3107 ReceiverType->isObjCQualifiedClassType()) {
3108 // Handle messages to Class.
3109 // We allow sending a message to a qualified Class ("Class<foo>"), which
3110 // is ok as long as one of the protocols implements the selector (if not,
3111 // warn).
3112 if (!ReceiverType->isObjCClassOrClassKindOfType()) {
3113 const ObjCObjectPointerType *QClassTy
3114 = ReceiverType->getAsObjCQualifiedClassType();
3115 // Search protocols for class methods.
3116 Method = LookupMethodInQualifiedType(Sel, QClassTy, false);
3117 if (!Method) {
3118 Method = LookupMethodInQualifiedType(Sel, QClassTy, true);
3119 // warn if instance method found for a Class message.
3121 Diag(SelLoc, diag::warn_instance_method_on_class_found)
3122 << Method->getSelector() << Sel;
3123 Diag(Method->getLocation(), diag::note_method_declared_at)
3124 << Method->getDeclName();
3125 }
3126 }
3127 } else {
3128 if (ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl()) {
3129 if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
3130 // As a guess, try looking for the method in the current interface.
3131 // This very well may not produce the "right" method.
3132
3133 // First check the public methods in the class interface.
3134 Method = ClassDecl->lookupClassMethod(Sel);
3135
3136 if (!Method)
3137 Method = ClassDecl->lookupPrivateClassMethod(Sel);
3138
3139 if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs))
3140 return ExprError();
3141 }
3142 }
3143 if (!Method) {
3144 // If not messaging 'self', look for any factory method named 'Sel'.
3145 if (!Receiver || !isSelfExpr(Receiver)) {
3146 // If no class (factory) method was found, check if an _instance_
3147 // method of the same name exists in the root class only.
3150 false/*InstanceFirst*/,
3151 true/*CheckTheOther*/);
3152 if (!Methods.empty()) {
3153 // We choose the first method as the initial candidate, then try
3154 // to select a better one.
3155 Method = Methods[0];
3156
3157 // If we find an instance method, emit warning.
3158 if (Method->isInstanceMethod()) {
3159 if (const ObjCInterfaceDecl *ID =
3160 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
3161 if (ID->getSuperClass())
3162 Diag(SelLoc, diag::warn_root_inst_method_not_found)
3163 << Sel << SourceRange(LBracLoc, RBracLoc);
3164 }
3165 }
3166
3167 if (ObjCMethodDecl *BestMethod = SemaRef.SelectBestMethod(
3168 Sel, ArgsIn, Method->isInstanceMethod(), Methods))
3169 Method = BestMethod;
3170 }
3171 }
3172 }
3173 }
3174 } else {
3175 ObjCInterfaceDecl *ClassDecl = nullptr;
3176
3177 // We allow sending a message to a qualified ID ("id<foo>"), which is ok as
3178 // long as one of the protocols implements the selector (if not, warn).
3179 // And as long as message is not deprecated/unavailable (warn if it is).
3180 if (const ObjCObjectPointerType *QIdTy
3181 = ReceiverType->getAsObjCQualifiedIdType()) {
3182 // Search protocols for instance methods.
3183 Method = LookupMethodInQualifiedType(Sel, QIdTy, true);
3184 if (!Method)
3185 Method = LookupMethodInQualifiedType(Sel, QIdTy, false);
3186 if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs))
3187 return ExprError();
3188 } else if (const ObjCObjectPointerType *OCIType
3189 = ReceiverType->getAsObjCInterfacePointerType()) {
3190 // We allow sending a message to a pointer to an interface (an object).
3191 ClassDecl = OCIType->getInterfaceDecl();
3192
3193 // Try to complete the type. Under ARC, this is a hard error from which
3194 // we don't try to recover.
3195 // FIXME: In the non-ARC case, this will still be a hard error if the
3196 // definition is found in a module that's not visible.
3197 const ObjCInterfaceDecl *forwardClass = nullptr;
3198 if (SemaRef.RequireCompleteType(
3199 Loc, OCIType->getPointeeType(),
3200 getLangOpts().ObjCAutoRefCount
3201 ? diag::err_arc_receiver_forward_instance
3202 : diag::warn_receiver_forward_instance,
3203 RecRange)) {
3204 if (getLangOpts().ObjCAutoRefCount)
3205 return ExprError();
3206
3207 forwardClass = OCIType->getInterfaceDecl();
3208 Diag(Receiver ? Receiver->getBeginLoc() : SuperLoc,
3209 diag::note_receiver_is_id);
3210 Method = nullptr;
3211 } else {
3212 Method = ClassDecl->lookupInstanceMethod(Sel);
3213 }
3214
3215 if (!Method)
3216 // Search protocol qualifiers.
3217 Method = LookupMethodInQualifiedType(Sel, OCIType, true);
3218
3219 if (!Method) {
3220 // If we have implementations in scope, check "private" methods.
3221 Method = ClassDecl->lookupPrivateMethod(Sel);
3222
3223 if (!Method && getLangOpts().ObjCAutoRefCount) {
3224 Diag(SelLoc, diag::err_arc_may_not_respond)
3225 << OCIType->getPointeeType() << Sel << RecRange
3226 << SourceRange(SelectorLocs.front(), SelectorLocs.back());
3227 return ExprError();
3228 }
3229
3230 if (!Method && (!Receiver || !isSelfExpr(Receiver))) {
3231 // If we still haven't found a method, look in the global pool. This
3232 // behavior isn't very desirable, however we need it for GCC
3233 // compatibility. FIXME: should we deviate??
3234 if (OCIType->qual_empty()) {
3237 true/*InstanceFirst*/,
3238 false/*CheckTheOther*/);
3239 if (!Methods.empty()) {
3240 // We choose the first method as the initial candidate, then try
3241 // to select a better one.
3242 Method = Methods[0];
3243
3244 if (ObjCMethodDecl *BestMethod = SemaRef.SelectBestMethod(
3245 Sel, ArgsIn, Method->isInstanceMethod(), Methods))
3246 Method = BestMethod;
3247
3249 SourceRange(LBracLoc, RBracLoc),
3250 true/*receiverIdOrClass*/,
3251 Methods);
3252 }
3253 if (Method && !forwardClass)
3254 Diag(SelLoc, diag::warn_maynot_respond)
3255 << OCIType->getInterfaceDecl()->getIdentifier()
3256 << Sel << RecRange;
3257 }
3258 }
3259 }
3260 if (Method &&
3261 SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, forwardClass))
3262 return ExprError();
3263 } else {
3264 // Reject other random receiver types (e.g. structs).
3265 Diag(Loc, diag::err_bad_receiver_type) << ReceiverType << RecRange;
3266 return ExprError();
3267 }
3268 }
3269 }
3270
3271 FunctionScopeInfo *DIFunctionScopeInfo =
3272 (Method && Method->getMethodFamily() == OMF_init)
3273 ? SemaRef.getEnclosingFunction()
3274 : nullptr;
3275
3276 if (Method && Method->isDirectMethod()) {
3277 if (ReceiverType->isObjCIdType() && !isImplicit) {
3278 Diag(Receiver->getExprLoc(),
3279 diag::err_messaging_unqualified_id_with_direct_method);
3280 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
3281 << Method->getDeclName();
3282 }
3283
3284 // Under ARC, self can't be assigned, and doing a direct call to `self`
3285 // when it's a Class is hence safe. For other cases, we can't trust `self`
3286 // is what we think it is, so we reject it.
3287 if (ReceiverType->isObjCClassType() && !isImplicit &&
3288 !(Receiver->isObjCSelfExpr() && getLangOpts().ObjCAutoRefCount)) {
3289 {
3290 auto Builder = Diag(Receiver->getExprLoc(),
3291 diag::err_messaging_class_with_direct_method);
3292 if (Receiver->isObjCSelfExpr()) {
3293 Builder.AddFixItHint(FixItHint::CreateReplacement(
3294 RecRange, Method->getClassInterface()->getName()));
3295 }
3296 }
3297 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
3298 << Method->getDeclName();
3299 }
3300
3301 if (SuperLoc.isValid()) {
3302 {
3303 auto Builder =
3304 Diag(SuperLoc, diag::err_messaging_super_with_direct_method);
3305 if (ReceiverType->isObjCClassType()) {
3306 Builder.AddFixItHint(FixItHint::CreateReplacement(
3307 SuperLoc, Method->getClassInterface()->getName()));
3308 } else {
3309 Builder.AddFixItHint(FixItHint::CreateReplacement(SuperLoc, "self"));
3310 }
3311 }
3312 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
3313 << Method->getDeclName();
3314 }
3315 } else if (ReceiverType->isObjCIdType() && !isImplicit) {
3316 Diag(Receiver->getExprLoc(), diag::warn_messaging_unqualified_id);
3317 }
3318
3319 if (DIFunctionScopeInfo &&
3320 DIFunctionScopeInfo->ObjCIsDesignatedInit &&
3321 (SuperLoc.isValid() || isSelfExpr(Receiver))) {
3322 bool isDesignatedInitChain = false;
3323 if (SuperLoc.isValid()) {
3324 if (const ObjCObjectPointerType *
3325 OCIType = ReceiverType->getAsObjCInterfacePointerType()) {
3326 if (const ObjCInterfaceDecl *ID = OCIType->getInterfaceDecl()) {
3327 // Either we know this is a designated initializer or we
3328 // conservatively assume it because we don't know for sure.
3329 if (!ID->declaresOrInheritsDesignatedInitializers() ||
3330 ID->isDesignatedInitializer(Sel)) {
3331 isDesignatedInitChain = true;
3332 DIFunctionScopeInfo->ObjCWarnForNoDesignatedInitChain = false;
3333 }
3334 }
3335 }
3336 }
3337 if (!isDesignatedInitChain) {
3338 const ObjCMethodDecl *InitMethod = nullptr;
3339 auto *CurMD = SemaRef.getCurMethodDecl();
3340 assert(CurMD && "Current method declaration should not be null");
3341 bool isDesignated =
3342 CurMD->isDesignatedInitializerForTheInterface(&InitMethod);
3343 assert(isDesignated && InitMethod);
3344 (void)isDesignated;
3345 Diag(SelLoc, SuperLoc.isValid() ?
3346 diag::warn_objc_designated_init_non_designated_init_call :
3347 diag::warn_objc_designated_init_non_super_designated_init_call);
3348 Diag(InitMethod->getLocation(),
3349 diag::note_objc_designated_init_marked_here);
3350 }
3351 }
3352
3353 if (DIFunctionScopeInfo &&
3354 DIFunctionScopeInfo->ObjCIsSecondaryInit &&
3355 (SuperLoc.isValid() || isSelfExpr(Receiver))) {
3356 if (SuperLoc.isValid()) {
3357 Diag(SelLoc, diag::warn_objc_secondary_init_super_init_call);
3358 } else {
3359 DIFunctionScopeInfo->ObjCWarnForNoInitDelegation = false;
3360 }
3361 }
3362
3363 // Check the message arguments.
3364 unsigned NumArgs = ArgsIn.size();
3365 Expr **Args = ArgsIn.data();
3366 QualType ReturnType;
3368 bool ClassMessage = (ReceiverType->isObjCClassType() ||
3369 ReceiverType->isObjCQualifiedClassType());
3370 if (CheckMessageArgumentTypes(Receiver, ReceiverType,
3371 MultiExprArg(Args, NumArgs), Sel, SelectorLocs,
3372 Method, ClassMessage, SuperLoc.isValid(),
3373 LBracLoc, RBracLoc, RecRange, ReturnType, VK))
3374 return ExprError();
3375
3376 if (Method && !Method->getReturnType()->isVoidType() &&
3377 SemaRef.RequireCompleteType(
3378 LBracLoc, Method->getReturnType(),
3379 diag::err_illegal_message_expr_incomplete_type))
3380 return ExprError();
3381
3382 // In ARC, forbid the user from sending messages to
3383 // retain/release/autorelease/dealloc/retainCount explicitly.
3384 if (getLangOpts().ObjCAutoRefCount) {
3385 ObjCMethodFamily family =
3386 (Method ? Method->getMethodFamily() : Sel.getMethodFamily());
3387 switch (family) {
3388 case OMF_init:
3389 if (Method)
3390 checkInitMethod(Method, ReceiverType);
3391 break;
3392
3393 case OMF_None:
3394 case OMF_alloc:
3395 case OMF_copy:
3396 case OMF_finalize:
3397 case OMF_mutableCopy:
3398 case OMF_new:
3399 case OMF_self:
3400 case OMF_initialize:
3401 break;
3402
3403 case OMF_dealloc:
3404 case OMF_retain:
3405 case OMF_release:
3406 case OMF_autorelease:
3407 case OMF_retainCount:
3408 Diag(SelLoc, diag::err_arc_illegal_explicit_message)
3409 << Sel << RecRange;
3410 break;
3411
3413 if (Method && NumArgs >= 1) {
3414 if (const auto *SelExp =
3415 dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens())) {
3416 Selector ArgSel = SelExp->getSelector();
3417 ObjCMethodDecl *SelMethod =
3419 SelExp->getSourceRange());
3420 if (!SelMethod)
3421 SelMethod =
3423 SelExp->getSourceRange());
3424 if (SelMethod) {
3425 ObjCMethodFamily SelFamily = SelMethod->getMethodFamily();
3426 switch (SelFamily) {
3427 case OMF_alloc:
3428 case OMF_copy:
3429 case OMF_mutableCopy:
3430 case OMF_new:
3431 case OMF_init:
3432 // Issue error, unless ns_returns_not_retained.
3433 if (!SelMethod->hasAttr<NSReturnsNotRetainedAttr>()) {
3434 // selector names a +1 method
3435 Diag(SelLoc,
3436 diag::err_arc_perform_selector_retains);
3437 Diag(SelMethod->getLocation(), diag::note_method_declared_at)
3438 << SelMethod->getDeclName();
3439 }
3440 break;
3441 default:
3442 // +0 call. OK. unless ns_returns_retained.
3443 if (SelMethod->hasAttr<NSReturnsRetainedAttr>()) {
3444 // selector names a +1 method
3445 Diag(SelLoc,
3446 diag::err_arc_perform_selector_retains);
3447 Diag(SelMethod->getLocation(), diag::note_method_declared_at)
3448 << SelMethod->getDeclName();
3449 }
3450 break;
3451 }
3452 }
3453 } else {
3454 // error (may leak).
3455 Diag(SelLoc, diag::warn_arc_perform_selector_leaks);
3456 Diag(Args[0]->getExprLoc(), diag::note_used_here);
3457 }
3458 }
3459 break;
3460 }
3461 }
3462
3464
3465 // Construct the appropriate ObjCMessageExpr instance.
3467 if (SuperLoc.isValid())
3469 Context, ReturnType, VK, LBracLoc, SuperLoc, /*IsInstanceSuper=*/true,
3470 ReceiverType, Sel, SelectorLocs, Method, ArrayRef(Args, NumArgs),
3471 RBracLoc, isImplicit);
3472 else {
3474 Context, ReturnType, VK, LBracLoc, Receiver, Sel, SelectorLocs, Method,
3475 ArrayRef(Args, NumArgs), RBracLoc, isImplicit);
3476 if (!isImplicit)
3478 }
3479 if (Method) {
3480 bool IsClassObjectCall = ClassMessage;
3481 // 'self' message receivers in class methods should be treated as message
3482 // sends to the class object in order for the semantic checks to be
3483 // performed correctly. Messages to 'super' already count as class messages,
3484 // so they don't need to be handled here.
3485 if (Receiver && isSelfExpr(Receiver)) {
3486 if (const auto *OPT = ReceiverType->getAs<ObjCObjectPointerType>()) {
3487 if (OPT->getObjectType()->isObjCClass()) {
3488 if (const auto *CurMeth = SemaRef.getCurMethodDecl()) {
3489 IsClassObjectCall = true;
3490 ReceiverType =
3491 Context.getObjCInterfaceType(CurMeth->getClassInterface());
3492 }
3493 }
3494 }
3495 }
3496 checkFoundationAPI(SemaRef, SelLoc, Method, ArrayRef(Args, NumArgs),
3497 ReceiverType, IsClassObjectCall);
3498 }
3499
3500 if (getLangOpts().ObjCAutoRefCount) {
3501 // In ARC, annotate delegate init calls.
3502 if (Result->getMethodFamily() == OMF_init &&
3503 (SuperLoc.isValid() || isSelfExpr(Receiver))) {
3504 // Only consider init calls *directly* in init implementations,
3505 // not within blocks.
3506 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext);
3507 if (method && method->getMethodFamily() == OMF_init) {
3508 // The implicit assignment to self means we also don't want to
3509 // consume the result.
3510 Result->setDelegateInitCall(true);
3511 return Result;
3512 }
3513 }
3514
3515 // In ARC, check for message sends which are likely to introduce
3516 // retain cycles.
3518 }
3519
3520 if (getLangOpts().ObjCWeak) {
3521 if (!isImplicit && Method) {
3522 if (const ObjCPropertyDecl *Prop = Method->findPropertyDecl()) {
3523 bool IsWeak =
3524 Prop->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak;
3525 if (!IsWeak && Sel.isUnarySelector())
3526 IsWeak = ReturnType.getObjCLifetime() & Qualifiers::OCL_Weak;
3527 if (IsWeak && !SemaRef.isUnevaluatedContext() &&
3528 !getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak,
3529 LBracLoc))
3530 SemaRef.getCurFunction()->recordUseOfWeak(Result, Prop);
3531 }
3532 }
3533 }
3534
3536
3537 return SemaRef.MaybeBindToTemporary(Result);
3538}
3539
3541 if (ObjCSelectorExpr *OSE =
3542 dyn_cast<ObjCSelectorExpr>(Arg->IgnoreParenCasts())) {
3543 Selector Sel = OSE->getSelector();
3544 SourceLocation Loc = OSE->getAtLoc();
3545 auto Pos = S.ReferencedSelectors.find(Sel);
3546 if (Pos != S.ReferencedSelectors.end() && Pos->second == Loc)
3547 S.ReferencedSelectors.erase(Pos);
3548 }
3549}
3550
3551// ActOnInstanceMessage - used for both unary and keyword messages.
3552// ArgExprs is optional - if it is present, the number of expressions
3553// is obtained from Sel.getNumArgs().
3555 Selector Sel, SourceLocation LBracLoc,
3556 ArrayRef<SourceLocation> SelectorLocs,
3557 SourceLocation RBracLoc,
3558 MultiExprArg Args) {
3559 ASTContext &Context = getASTContext();
3560 if (!Receiver)
3561 return ExprError();
3562
3563 // A ParenListExpr can show up while doing error recovery with invalid code.
3564 if (isa<ParenListExpr>(Receiver)) {
3566 SemaRef.MaybeConvertParenListExprToParenExpr(S, Receiver);
3567 if (Result.isInvalid()) return ExprError();
3568 Receiver = Result.get();
3569 }
3570
3571 if (RespondsToSelectorSel.isNull()) {
3572 IdentifierInfo *SelectorId = &Context.Idents.get("respondsToSelector");
3573 RespondsToSelectorSel = Context.Selectors.getUnarySelector(SelectorId);
3574 }
3575 if (Sel == RespondsToSelectorSel)
3576 RemoveSelectorFromWarningCache(*this, Args[0]);
3577
3578 return BuildInstanceMessage(Receiver, Receiver->getType(),
3579 /*SuperLoc=*/SourceLocation(), Sel,
3580 /*Method=*/nullptr, LBracLoc, SelectorLocs,
3581 RBracLoc, Args);
3582}
3583
3585 /// int, void, struct A
3587
3588 /// id, void (^)()
3590
3591 /// id*, id***, void (^*)(),
3593
3594 /// void* might be a normal C type, or it might a CF type.
3596
3597 /// struct A*
3599};
3600
3602 return (ACTC == ACTC_retainable ||
3603 ACTC == ACTC_coreFoundation ||
3604 ACTC == ACTC_voidPtr);
3605}
3606
3608 return ACTC == ACTC_none ||
3609 ACTC == ACTC_voidPtr ||
3610 ACTC == ACTC_coreFoundation;
3611}
3612
3614 bool isIndirect = false;
3615
3616 // Ignore an outermost reference type.
3617 if (const ReferenceType *ref = type->getAs<ReferenceType>()) {
3618 type = ref->getPointeeType();
3619 isIndirect = true;
3620 }
3621
3622 // Drill through pointers and arrays recursively.
3623 while (true) {
3624 if (const PointerType *ptr = type->getAs<PointerType>()) {
3625 type = ptr->getPointeeType();
3626
3627 // The first level of pointer may be the innermost pointer on a CF type.
3628 if (!isIndirect) {
3629 if (type->isVoidType()) return ACTC_voidPtr;
3630 if (type->isRecordType()) return ACTC_coreFoundation;
3631 }
3632 } else if (const ArrayType *array = type->getAsArrayTypeUnsafe()) {
3633 type = QualType(array->getElementType()->getBaseElementTypeUnsafe(), 0);
3634 } else {
3635 break;
3636 }
3637 isIndirect = true;
3638 }
3639
3640 if (isIndirect) {
3641 if (type->isObjCARCBridgableType())
3643 return ACTC_none;
3644 }
3645
3646 if (type->isObjCARCBridgableType())
3647 return ACTC_retainable;
3648
3649 return ACTC_none;
3650}
3651
3652namespace {
3653 /// A result from the cast checker.
3654 enum ACCResult {
3655 /// Cannot be casted.
3656 ACC_invalid,
3657
3658 /// Can be safely retained or not retained.
3659 ACC_bottom,
3660
3661 /// Can be casted at +0.
3662 ACC_plusZero,
3663
3664 /// Can be casted at +1.
3665 ACC_plusOne
3666 };
3667 ACCResult merge(ACCResult left, ACCResult right) {
3668 if (left == right) return left;
3669 if (left == ACC_bottom) return right;
3670 if (right == ACC_bottom) return left;
3671 return ACC_invalid;
3672 }
3673
3674 /// A checker which white-lists certain expressions whose conversion
3675 /// to or from retainable type would otherwise be forbidden in ARC.
3676 class ARCCastChecker : public StmtVisitor<ARCCastChecker, ACCResult> {
3677 typedef StmtVisitor<ARCCastChecker, ACCResult> super;
3678
3679 ASTContext &Context;
3680 ARCConversionTypeClass SourceClass;
3681 ARCConversionTypeClass TargetClass;
3682 bool Diagnose;
3683
3684 static bool isCFType(QualType type) {
3685 // Someday this can use ns_bridged. For now, it has to do this.
3686 return type->isCARCBridgableType();
3687 }
3688
3689 public:
3690 ARCCastChecker(ASTContext &Context, ARCConversionTypeClass source,
3691 ARCConversionTypeClass target, bool diagnose)
3692 : Context(Context), SourceClass(source), TargetClass(target),
3693 Diagnose(diagnose) {}
3694
3695 using super::Visit;
3696 ACCResult Visit(Expr *e) {
3697 return super::Visit(e->IgnoreParens());
3698 }
3699
3700 ACCResult VisitStmt(Stmt *s) {
3701 return ACC_invalid;
3702 }
3703
3704 /// Null pointer constants can be casted however you please.
3705 ACCResult VisitExpr(Expr *e) {
3707 return ACC_bottom;
3708 return ACC_invalid;
3709 }
3710
3711 /// Constant initializer Objective-C literals can be safely casted.
3712 ACCResult VisitObjCObjectLiteral(ObjCObjectLiteral *OL) {
3713 // If we're casting to any retainable type, go ahead. Global
3714 // strings and constant literals are immune to retains, so this is bottom.
3715 if (OL->isGlobalAllocation() || isAnyRetainable(TargetClass))
3716 return ACC_bottom;
3717
3718 return ACC_invalid;
3719 }
3720
3721 ACCResult VisitObjCStringLiteral(ObjCStringLiteral *SL) {
3722 return VisitObjCObjectLiteral(SL);
3723 }
3724
3725 ACCResult VisitObjCBoxedExpr(ObjCBoxedExpr *OBE) {
3726 return VisitObjCObjectLiteral(OBE);
3727 }
3728
3729 ACCResult VisitObjCArrayLiteral(ObjCArrayLiteral *AL) {
3730 return VisitObjCObjectLiteral(AL);
3731 }
3732
3733 ACCResult VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *DL) {
3734 return VisitObjCObjectLiteral(DL);
3735 }
3736
3737 /// Look through certain implicit and explicit casts.
3738 ACCResult VisitCastExpr(CastExpr *e) {
3739 switch (e->getCastKind()) {
3740 case CK_NullToPointer:
3741 return ACC_bottom;
3742
3743 case CK_NoOp:
3744 case CK_LValueToRValue:
3745 case CK_BitCast:
3746 case CK_CPointerToObjCPointerCast:
3747 case CK_BlockPointerToObjCPointerCast:
3748 case CK_AnyPointerToBlockPointerCast:
3749 return Visit(e->getSubExpr());
3750
3751 default:
3752 return ACC_invalid;
3753 }
3754 }
3755
3756 /// Look through unary extension.
3757 ACCResult VisitUnaryExtension(UnaryOperator *e) {
3758 return Visit(e->getSubExpr());
3759 }
3760
3761 /// Ignore the LHS of a comma operator.
3762 ACCResult VisitBinComma(BinaryOperator *e) {
3763 return Visit(e->getRHS());
3764 }
3765
3766 /// Conditional operators are okay if both sides are okay.
3767 ACCResult VisitConditionalOperator(ConditionalOperator *e) {
3768 ACCResult left = Visit(e->getTrueExpr());
3769 if (left == ACC_invalid) return ACC_invalid;
3770 return merge(left, Visit(e->getFalseExpr()));
3771 }
3772
3773 /// Look through pseudo-objects.
3774 ACCResult VisitPseudoObjectExpr(PseudoObjectExpr *e) {
3775 // If we're getting here, we should always have a result.
3776 return Visit(e->getResultExpr());
3777 }
3778
3779 /// Statement expressions are okay if their result expression is okay.
3780 ACCResult VisitStmtExpr(StmtExpr *e) {
3781 return Visit(e->getSubStmt()->body_back());
3782 }
3783
3784 /// Some declaration references are okay.
3785 ACCResult VisitDeclRefExpr(DeclRefExpr *e) {
3786 VarDecl *var = dyn_cast<VarDecl>(e->getDecl());
3787 // References to global constants are okay.
3788 if (isAnyRetainable(TargetClass) &&
3789 isAnyRetainable(SourceClass) &&
3790 var &&
3791 !var->hasDefinition(Context) &&
3792 var->getType().isConstQualified()) {
3793
3794 // In system headers, they can also be assumed to be immune to retains.
3795 // These are things like 'kCFStringTransformToLatin'.
3796 if (Context.getSourceManager().isInSystemHeader(var->getLocation()))
3797 return ACC_bottom;
3798
3799 return ACC_plusZero;
3800 }
3801
3802 // Nothing else.
3803 return ACC_invalid;
3804 }
3805
3806 /// Some calls are okay.
3807 ACCResult VisitCallExpr(CallExpr *e) {
3808 if (FunctionDecl *fn = e->getDirectCallee())
3809 if (ACCResult result = checkCallToFunction(fn))
3810 return result;
3811
3812 return super::VisitCallExpr(e);
3813 }
3814
3815 ACCResult checkCallToFunction(FunctionDecl *fn) {
3816 // Require a CF*Ref return type.
3817 if (!isCFType(fn->getReturnType()))
3818 return ACC_invalid;
3819
3820 if (!isAnyRetainable(TargetClass))
3821 return ACC_invalid;
3822
3823 // Honor an explicit 'not retained' attribute.
3824 if (fn->hasAttr<CFReturnsNotRetainedAttr>())
3825 return ACC_plusZero;
3826
3827 // Honor an explicit 'retained' attribute, except that for
3828 // now we're not going to permit implicit handling of +1 results,
3829 // because it's a bit frightening.
3830 if (fn->hasAttr<CFReturnsRetainedAttr>())
3831 return Diagnose ? ACC_plusOne
3832 : ACC_invalid; // ACC_plusOne if we start accepting this
3833
3834 // Recognize this specific builtin function, which is used by CFSTR.
3835 unsigned builtinID = fn->getBuiltinID();
3836 if (builtinID == Builtin::BI__builtin___CFStringMakeConstantString)
3837 return ACC_bottom;
3838
3839 // Otherwise, don't do anything implicit with an unaudited function.
3840 if (!fn->hasAttr<CFAuditedTransferAttr>())
3841 return ACC_invalid;
3842
3843 // Otherwise, it's +0 unless it follows the create convention.
3845 return Diagnose ? ACC_plusOne
3846 : ACC_invalid; // ACC_plusOne if we start accepting this
3847
3848 return ACC_plusZero;
3849 }
3850
3851 ACCResult VisitObjCMessageExpr(ObjCMessageExpr *e) {
3852 return checkCallToMethod(e->getMethodDecl());
3853 }
3854
3855 ACCResult VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *e) {
3856 ObjCMethodDecl *method;
3857 if (e->isExplicitProperty())
3859 else
3860 method = e->getImplicitPropertyGetter();
3861 return checkCallToMethod(method);
3862 }
3863
3864 ACCResult checkCallToMethod(ObjCMethodDecl *method) {
3865 if (!method) return ACC_invalid;
3866
3867 // Check for message sends to functions returning CF types. We
3868 // just obey the Cocoa conventions with these, even though the
3869 // return type is CF.
3870 if (!isAnyRetainable(TargetClass) || !isCFType(method->getReturnType()))
3871 return ACC_invalid;
3872
3873 // If the method is explicitly marked not-retained, it's +0.
3874 if (method->hasAttr<CFReturnsNotRetainedAttr>())
3875 return ACC_plusZero;
3876
3877 // If the method is explicitly marked as returning retained, or its
3878 // selector follows a +1 Cocoa convention, treat it as +1.
3879 if (method->hasAttr<CFReturnsRetainedAttr>())
3880 return ACC_plusOne;
3881
3882 switch (method->getSelector().getMethodFamily()) {
3883 case OMF_alloc:
3884 case OMF_copy:
3885 case OMF_mutableCopy:
3886 case OMF_new:
3887 return ACC_plusOne;
3888
3889 default:
3890 // Otherwise, treat it as +0.
3891 return ACC_plusZero;
3892 }
3893 }
3894 };
3895} // end anonymous namespace
3896
3897bool SemaObjC::isKnownName(StringRef name) {
3898 ASTContext &Context = getASTContext();
3899 if (name.empty())
3900 return false;
3901 LookupResult R(SemaRef, &Context.Idents.get(name), SourceLocation(),
3903 return SemaRef.LookupName(R, SemaRef.TUScope, false);
3904}
3905
3906template <typename DiagBuilderT>
3908 Sema &S, DiagBuilderT &DiagB, CheckedConversionKind CCK,
3909 SourceLocation afterLParen, QualType castType, Expr *castExpr,
3910 Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName) {
3911 // We handle C-style and implicit casts here.
3912 switch (CCK) {
3917 break;
3919 return;
3920 }
3921
3922 if (CFBridgeName) {
3924 if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) {
3925 SourceRange range(NCE->getOperatorLoc(),
3926 NCE->getAngleBrackets().getEnd());
3927 SmallString<32> BridgeCall;
3928
3930 char PrevChar = *SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
3932 BridgeCall += ' ';
3933
3934 BridgeCall += CFBridgeName;
3935 DiagB.AddFixItHint(FixItHint::CreateReplacement(range, BridgeCall));
3936 }
3937 return;
3938 }
3939 Expr *castedE = castExpr;
3940 if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(castedE))
3941 castedE = CCE->getSubExpr();
3942 castedE = castedE->IgnoreImpCasts();
3943 SourceRange range = castedE->getSourceRange();
3944
3945 SmallString<32> BridgeCall;
3946
3948 char PrevChar = *SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
3950 BridgeCall += ' ';
3951
3952 BridgeCall += CFBridgeName;
3953
3954 if (isa<ParenExpr>(castedE)) {
3955 DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
3956 BridgeCall));
3957 } else {
3958 BridgeCall += '(';
3959 DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
3960 BridgeCall));
3961 DiagB.AddFixItHint(FixItHint::CreateInsertion(
3962 S.getLocForEndOfToken(range.getEnd()),
3963 ")"));
3964 }
3965 return;
3966 }
3967
3969 DiagB.AddFixItHint(FixItHint::CreateInsertion(afterLParen, bridgeKeyword));
3970 } else if (CCK == CheckedConversionKind::OtherCast) {
3971 if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) {
3972 std::string castCode = "(";
3973 castCode += bridgeKeyword;
3974 castCode += castType.getAsString();
3975 castCode += ")";
3976 SourceRange Range(NCE->getOperatorLoc(),
3977 NCE->getAngleBrackets().getEnd());
3978 DiagB.AddFixItHint(FixItHint::CreateReplacement(Range, castCode));
3979 }
3980 } else {
3981 std::string castCode = "(";
3982 castCode += bridgeKeyword;
3983 castCode += castType.getAsString();
3984 castCode += ")";
3985 Expr *castedE = castExpr->IgnoreImpCasts();
3986 SourceRange range = castedE->getSourceRange();
3987 if (isa<ParenExpr>(castedE)) {
3988 DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
3989 castCode));
3990 } else {
3991 castCode += "(";
3992 DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
3993 castCode));
3994 DiagB.AddFixItHint(FixItHint::CreateInsertion(
3995 S.getLocForEndOfToken(range.getEnd()),
3996 ")"));
3997 }
3998 }
3999}
4000
4001template <typename T>
4002static inline T *getObjCBridgeAttr(const TypedefType *TD) {
4003 TypedefNameDecl *TDNDecl = TD->getDecl();
4004 QualType QT = TDNDecl->getUnderlyingType();
4005 if (QT->isPointerType()) {
4006 QT = QT->getPointeeType();
4007 if (const RecordType *RT = QT->getAsCanonical<RecordType>()) {
4008 for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {
4009 if (auto *attr = Redecl->getAttr<T>())
4010 return attr;
4011 }
4012 }
4013 }
4014 return nullptr;
4015}
4016
4017static ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttrFromType(QualType T,
4018 TypedefNameDecl *&TDNDecl) {
4019 while (const auto *TD = T->getAs<TypedefType>()) {
4020 TDNDecl = TD->getDecl();
4021 if (ObjCBridgeRelatedAttr *ObjCBAttr =
4023 return ObjCBAttr;
4024 T = TDNDecl->getUnderlyingType();
4025 }
4026 return nullptr;
4027}
4028
4030 QualType castType,
4031 ARCConversionTypeClass castACTC,
4032 Expr *castExpr, Expr *realCast,
4033 ARCConversionTypeClass exprACTC,
4035 SourceLocation loc =
4036 (castRange.isValid() ? castRange.getBegin() : castExpr->getExprLoc());
4037
4039 UnavailableAttr::IR_ARCForbiddenConversion))
4040 return;
4041
4042 QualType castExprType = castExpr->getType();
4043 // Defer emitting a diagnostic for bridge-related casts; that will be
4044 // handled by CheckObjCBridgeRelatedConversions.
4045 TypedefNameDecl *TDNDecl = nullptr;
4046 if ((castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable &&
4047 ObjCBridgeRelatedAttrFromType(castType, TDNDecl)) ||
4048 (exprACTC == ACTC_coreFoundation && castACTC == ACTC_retainable &&
4049 ObjCBridgeRelatedAttrFromType(castExprType, TDNDecl)))
4050 return;
4051
4052 unsigned srcKind = 0;
4053 switch (exprACTC) {
4054 case ACTC_none:
4056 case ACTC_voidPtr:
4057 srcKind = (castExprType->isPointerType() ? 1 : 0);
4058 break;
4059 case ACTC_retainable:
4060 srcKind = (castExprType->isBlockPointerType() ? 2 : 3);
4061 break;
4063 srcKind = 4;
4064 break;
4065 }
4066
4067 // Check whether this could be fixed with a bridge cast.
4068 SourceLocation afterLParen = S.getLocForEndOfToken(castRange.getBegin());
4069 SourceLocation noteLoc = afterLParen.isValid() ? afterLParen : loc;
4070
4071 unsigned convKindForDiag = Sema::isCast(CCK) ? 0 : 1;
4072
4073 // Bridge from an ARC type to a CF type.
4074 if (castACTC == ACTC_retainable && isAnyRetainable(exprACTC)) {
4075
4076 S.Diag(loc, diag::err_arc_cast_requires_bridge)
4077 << convKindForDiag
4078 << 2 // of C pointer type
4079 << castExprType
4080 << unsigned(castType->isBlockPointerType()) // to ObjC|block type
4081 << castType
4082 << castRange
4083 << castExpr->getSourceRange();
4084 bool br = S.ObjC().isKnownName("CFBridgingRelease");
4085 ACCResult CreateRule =
4086 ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr);
4087 assert(CreateRule != ACC_bottom && "This cast should already be accepted.");
4088 if (CreateRule != ACC_plusOne)
4089 {
4090 auto DiagB = (CCK != CheckedConversionKind::OtherCast)
4091 ? S.Diag(noteLoc, diag::note_arc_bridge)
4092 : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);
4093
4094 addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
4095 castType, castExpr, realCast, "__bridge ",
4096 nullptr);
4097 }
4098 if (CreateRule != ACC_plusZero)
4099 {
4100 auto DiagB = (CCK == CheckedConversionKind::OtherCast && !br)
4101 ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_transfer)
4102 << castExprType
4103 : S.Diag(br ? castExpr->getExprLoc() : noteLoc,
4104 diag::note_arc_bridge_transfer)
4105 << castExprType << br;
4106
4107 addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
4108 castType, castExpr, realCast, "__bridge_transfer ",
4109 br ? "CFBridgingRelease" : nullptr);
4110 }
4111
4112 return;
4113 }
4114
4115 // Bridge from a CF type to an ARC type.
4116 if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC)) {
4117 bool br = S.ObjC().isKnownName("CFBridgingRetain");
4118 S.Diag(loc, diag::err_arc_cast_requires_bridge)
4119 << convKindForDiag
4120 << unsigned(castExprType->isBlockPointerType()) // of ObjC|block type
4121 << castExprType
4122 << 2 // to C pointer type
4123 << castType
4124 << castRange
4125 << castExpr->getSourceRange();
4126 ACCResult CreateRule =
4127 ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr);
4128 assert(CreateRule != ACC_bottom && "This cast should already be accepted.");
4129 if (CreateRule != ACC_plusOne)
4130 {
4131 auto DiagB = (CCK != CheckedConversionKind::OtherCast)
4132 ? S.Diag(noteLoc, diag::note_arc_bridge)
4133 : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);
4134 addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
4135 castType, castExpr, realCast, "__bridge ",
4136 nullptr);
4137 }
4138 if (CreateRule != ACC_plusZero)
4139 {
4140 auto DiagB = (CCK == CheckedConversionKind::OtherCast && !br)
4141 ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_retained)
4142 << castType
4143 : S.Diag(br ? castExpr->getExprLoc() : noteLoc,
4144 diag::note_arc_bridge_retained)
4145 << castType << br;
4146
4147 addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
4148 castType, castExpr, realCast, "__bridge_retained ",
4149 br ? "CFBridgingRetain" : nullptr);
4150 }
4151
4152 return;
4153 }
4154
4155 S.Diag(loc, diag::err_arc_mismatched_cast)
4156 << !convKindForDiag
4157 << srcKind << castExprType << castType
4158 << castRange << castExpr->getSourceRange();
4159}
4160
4161template <typename TB>
4163 bool &HadTheAttribute, bool warn) {
4164 QualType T = castExpr->getType();
4165 HadTheAttribute = false;
4166 while (const auto *TD = T->getAs<TypedefType>()) {
4167 TypedefNameDecl *TDNDecl = TD->getDecl();
4168 if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
4169 if (const IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
4170 HadTheAttribute = true;
4171 if (Parm->isStr("id"))
4172 return true;
4173
4174 // Check for an existing type with this name.
4177 if (S.LookupName(R, S.TUScope)) {
4178 NamedDecl *Target = R.getFoundDecl();
4181 if (const ObjCObjectPointerType *InterfacePointerType =
4182 castType->getAsObjCInterfacePointerType()) {
4183 ObjCInterfaceDecl *CastClass
4184 = InterfacePointerType->getObjectType()->getInterface();
4185 if ((CastClass == ExprClass) ||
4186 (CastClass && CastClass->isSuperClassOf(ExprClass)))
4187 return true;
4188 if (warn)
4189 S.Diag(castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4190 << T << Target->getName() << castType->getPointeeType();
4191 return false;
4192 } else if (castType->isObjCIdType() ||
4194 castType, ExprClass)))
4195 // ok to cast to 'id'.
4196 // casting to id<p-list> is ok if bridge type adopts all of
4197 // p-list protocols.
4198 return true;
4199 else {
4200 if (warn) {
4201 S.Diag(castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4202 << T << Target->getName() << castType;
4203 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4204 S.Diag(Target->getBeginLoc(), diag::note_declared_at);
4205 }
4206 return false;
4207 }
4208 }
4209 } else if (!castType->isObjCIdType()) {
4210 S.Diag(castExpr->getBeginLoc(),
4211 diag::err_objc_cf_bridged_not_interface)
4212 << castExpr->getType() << Parm;
4213 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4214 }
4215 return true;
4216 }
4217 return false;
4218 }
4219 T = TDNDecl->getUnderlyingType();
4220 }
4221 return true;
4222}
4223
4224template <typename TB>
4226 bool &HadTheAttribute, bool warn) {
4227 QualType T = castType;
4228 HadTheAttribute = false;
4229 while (const auto *TD = T->getAs<TypedefType>()) {
4230 TypedefNameDecl *TDNDecl = TD->getDecl();
4231 if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
4232 if (const IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
4233 HadTheAttribute = true;
4234 if (Parm->isStr("id"))
4235 return true;
4236
4237 NamedDecl *Target = nullptr;
4238 // Check for an existing type with this name.
4241 if (S.LookupName(R, S.TUScope)) {
4242 Target = R.getFoundDecl();
4245 if (const ObjCObjectPointerType *InterfacePointerType =
4246 castExpr->getType()->getAsObjCInterfacePointerType()) {
4247 ObjCInterfaceDecl *ExprClass
4248 = InterfacePointerType->getObjectType()->getInterface();
4249 if ((CastClass == ExprClass) ||
4250 (ExprClass && CastClass->isSuperClassOf(ExprClass)))
4251 return true;
4252 if (warn) {
4253 S.Diag(castExpr->getBeginLoc(),
4254 diag::warn_objc_invalid_bridge_to_cf)
4255 << castExpr->getType()->getPointeeType() << T;
4256 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4257 }
4258 return false;
4259 } else if (castExpr->getType()->isObjCIdType() ||
4261 castExpr->getType(), CastClass)))
4262 // ok to cast an 'id' expression to a CFtype.
4263 // ok to cast an 'id<plist>' expression to CFtype provided plist
4264 // adopts all of CFtype's ObjetiveC's class plist.
4265 return true;
4266 else {
4267 if (warn) {
4268 S.Diag(castExpr->getBeginLoc(),
4269 diag::warn_objc_invalid_bridge_to_cf)
4270 << castExpr->getType() << castType;
4271 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4272 S.Diag(Target->getBeginLoc(), diag::note_declared_at);
4273 }
4274 return false;
4275 }
4276 }
4277 }
4278 S.Diag(castExpr->getBeginLoc(),
4279 diag::err_objc_ns_bridged_invalid_cfobject)
4280 << castExpr->getType() << castType;
4281 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4282 if (Target)
4283 S.Diag(Target->getBeginLoc(), diag::note_declared_at);
4284 return true;
4285 }
4286 return false;
4287 }
4288 T = TDNDecl->getUnderlyingType();
4289 }
4290 return true;
4291}
4292
4294 if (!getLangOpts().ObjC)
4295 return;
4296 // warn in presence of __bridge casting to or from a toll free bridge cast.
4299 if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) {
4300 bool HasObjCBridgeAttr;
4301 bool ObjCBridgeAttrWillNotWarn = CheckObjCBridgeNSCast<ObjCBridgeAttr>(
4302 SemaRef, castType, castExpr, HasObjCBridgeAttr, false);
4303 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4304 return;
4305 bool HasObjCBridgeMutableAttr;
4306 bool ObjCBridgeMutableAttrWillNotWarn =
4308 SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false);
4309 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4310 return;
4311
4312 if (HasObjCBridgeAttr)
4314 HasObjCBridgeAttr, true);
4315 else if (HasObjCBridgeMutableAttr)
4317 SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, true);
4318 }
4319 else if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable) {
4320 bool HasObjCBridgeAttr;
4321 bool ObjCBridgeAttrWillNotWarn = CheckObjCBridgeCFCast<ObjCBridgeAttr>(
4322 SemaRef, castType, castExpr, HasObjCBridgeAttr, false);
4323 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4324 return;
4325 bool HasObjCBridgeMutableAttr;
4326 bool ObjCBridgeMutableAttrWillNotWarn =
4328 SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false);
4329 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4330 return;
4331
4332 if (HasObjCBridgeAttr)
4334 HasObjCBridgeAttr, true);
4335 else if (HasObjCBridgeMutableAttr)
4337 SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, true);
4338 }
4339}
4340
4342 QualType SrcType = castExpr->getType();
4343 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(castExpr)) {
4344 if (PRE->isExplicitProperty()) {
4345 if (ObjCPropertyDecl *PDecl = PRE->getExplicitProperty())
4346 SrcType = PDecl->getType();
4347 }
4348 else if (PRE->isImplicitProperty()) {
4349 if (ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter())
4350 SrcType = Getter->getReturnType();
4351 }
4352 }
4353
4356 if (srcExprACTC != ACTC_retainable || castExprACTC != ACTC_coreFoundation)
4357 return;
4358 CheckObjCBridgeRelatedConversions(castExpr->getBeginLoc(), castType, SrcType,
4359 castExpr);
4360}
4361
4363 CastKind &Kind) {
4364 if (!getLangOpts().ObjC)
4365 return false;
4366 ARCConversionTypeClass exprACTC =
4369 if ((castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) ||
4370 (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable)) {
4372 Kind = (castACTC == ACTC_coreFoundation) ? CK_BitCast
4373 : CK_CPointerToObjCPointerCast;
4374 return true;
4375 }
4376 return false;
4377}
4378
4380 SourceLocation Loc, QualType DestType, QualType SrcType,
4381 ObjCInterfaceDecl *&RelatedClass, ObjCMethodDecl *&ClassMethod,
4382 ObjCMethodDecl *&InstanceMethod, TypedefNameDecl *&TDNDecl, bool CfToNs,
4383 bool Diagnose) {
4384 ASTContext &Context = getASTContext();
4385 QualType T = CfToNs ? SrcType : DestType;
4386 ObjCBridgeRelatedAttr *ObjCBAttr = ObjCBridgeRelatedAttrFromType(T, TDNDecl);
4387 if (!ObjCBAttr)
4388 return false;
4389
4390 const IdentifierInfo *RCId = ObjCBAttr->getRelatedClass();
4391 const IdentifierInfo *CMId = ObjCBAttr->getClassMethod();
4392 const IdentifierInfo *IMId = ObjCBAttr->getInstanceMethod();
4393 if (!RCId)
4394 return false;
4395 NamedDecl *Target = nullptr;
4396 // Check for an existing type with this name.
4399 if (!SemaRef.LookupName(R, SemaRef.TUScope)) {
4400 if (Diagnose) {
4401 Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId
4402 << SrcType << DestType;
4403 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4404 }
4405 return false;
4406 }
4407 Target = R.getFoundDecl();
4409 RelatedClass = cast<ObjCInterfaceDecl>(Target);
4410 else {
4411 if (Diagnose) {
4412 Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId
4413 << SrcType << DestType;
4414 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4415 if (Target)
4416 Diag(Target->getBeginLoc(), diag::note_declared_at);
4417 }
4418 return false;
4419 }
4420
4421 // Check for an existing class method with the given selector name.
4422 if (CfToNs && CMId) {
4423 Selector Sel = Context.Selectors.getUnarySelector(CMId);
4424 ClassMethod = RelatedClass->lookupMethod(Sel, false);
4425 if (!ClassMethod) {
4426 if (Diagnose) {
4427 Diag(Loc, diag::err_objc_bridged_related_known_method)
4428 << SrcType << DestType << Sel << false;
4429 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4430 }
4431 return false;
4432 }
4433 }
4434
4435 // Check for an existing instance method with the given selector name.
4436 if (!CfToNs && IMId) {
4437 Selector Sel = Context.Selectors.getNullarySelector(IMId);
4438 InstanceMethod = RelatedClass->lookupMethod(Sel, true);
4439 if (!InstanceMethod) {
4440 if (Diagnose) {
4441 Diag(Loc, diag::err_objc_bridged_related_known_method)
4442 << SrcType << DestType << Sel << true;
4443 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4444 }
4445 return false;
4446 }
4447 }
4448 return true;
4449}
4450
4452 QualType DestType,
4453 QualType SrcType,
4454 Expr *&SrcExpr,
4455 bool Diagnose) {
4456 ASTContext &Context = getASTContext();
4459 bool CfToNs = (rhsExprACTC == ACTC_coreFoundation && lhsExprACTC == ACTC_retainable);
4460 bool NsToCf = (rhsExprACTC == ACTC_retainable && lhsExprACTC == ACTC_coreFoundation);
4461 if (!CfToNs && !NsToCf)
4462 return false;
4463
4464 ObjCInterfaceDecl *RelatedClass;
4465 ObjCMethodDecl *ClassMethod = nullptr;
4466 ObjCMethodDecl *InstanceMethod = nullptr;
4467 TypedefNameDecl *TDNDecl = nullptr;
4468 if (!checkObjCBridgeRelatedComponents(Loc, DestType, SrcType, RelatedClass,
4469 ClassMethod, InstanceMethod, TDNDecl,
4470 CfToNs, Diagnose))
4471 return false;
4472
4473 if (CfToNs) {
4474 // Implicit conversion from CF to ObjC object is needed.
4475 if (ClassMethod) {
4476 if (Diagnose) {
4477 std::string ExpressionString = "[";
4478 ExpressionString += RelatedClass->getNameAsString();
4479 ExpressionString += " ";
4480 ExpressionString += ClassMethod->getSelector().getAsString();
4481 SourceLocation SrcExprEndLoc =
4482 SemaRef.getLocForEndOfToken(SrcExpr->getEndLoc());
4483 // Provide a fixit: [RelatedClass ClassMethod SrcExpr]
4484 Diag(Loc, diag::err_objc_bridged_related_known_method)
4485 << SrcType << DestType << ClassMethod->getSelector() << false
4487 ExpressionString)
4488 << FixItHint::CreateInsertion(SrcExprEndLoc, "]");
4489 Diag(RelatedClass->getBeginLoc(), diag::note_declared_at);
4490 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4491
4492 QualType receiverType = Context.getObjCInterfaceType(RelatedClass);
4493 // Argument.
4494 Expr *args[] = { SrcExpr };
4495 ExprResult msg = BuildClassMessageImplicit(receiverType, false,
4496 ClassMethod->getLocation(),
4497 ClassMethod->getSelector(), ClassMethod,
4498 MultiExprArg(args, 1));
4499 SrcExpr = msg.get();
4500 }
4501 return true;
4502 }
4503 }
4504 else {
4505 // Implicit conversion from ObjC type to CF object is needed.
4506 if (InstanceMethod) {
4507 if (Diagnose) {
4508 std::string ExpressionString;
4509 SourceLocation SrcExprEndLoc =
4510 SemaRef.getLocForEndOfToken(SrcExpr->getEndLoc());
4511 if (InstanceMethod->isPropertyAccessor())
4512 if (const ObjCPropertyDecl *PDecl =
4513 InstanceMethod->findPropertyDecl()) {
4514 // fixit: ObjectExpr.propertyname when it is aproperty accessor.
4515 ExpressionString = ".";
4516 ExpressionString += PDecl->getNameAsString();
4517 Diag(Loc, diag::err_objc_bridged_related_known_method)
4518 << SrcType << DestType << InstanceMethod->getSelector() << true
4519 << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
4520 }
4521 if (ExpressionString.empty()) {
4522 // Provide a fixit: [ObjectExpr InstanceMethod]
4523 ExpressionString = " ";
4524 ExpressionString += InstanceMethod->getSelector().getAsString();
4525 ExpressionString += "]";
4526
4527 Diag(Loc, diag::err_objc_bridged_related_known_method)
4528 << SrcType << DestType << InstanceMethod->getSelector() << true
4529 << FixItHint::CreateInsertion(SrcExpr->getBeginLoc(), "[")
4530 << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
4531 }
4532 Diag(RelatedClass->getBeginLoc(), diag::note_declared_at);
4533 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4534
4536 SrcExpr, SrcType, InstanceMethod->getLocation(),
4537 InstanceMethod->getSelector(), InstanceMethod, {});
4538 SrcExpr = msg.get();
4539 }
4540 return true;
4541 }
4542 }
4543 return false;
4544}
4545
4549 bool Diagnose, bool DiagnoseCFAudited,
4550 BinaryOperatorKind Opc, bool IsReinterpretCast) {
4551 ASTContext &Context = getASTContext();
4552 QualType castExprType = castExpr->getType();
4553
4554 // For the purposes of the classification, we assume reference types
4555 // will bind to temporaries.
4556 QualType effCastType = castType;
4557 if (const ReferenceType *ref = castType->getAs<ReferenceType>())
4558 effCastType = ref->getPointeeType();
4559
4562 if (exprACTC == castACTC) {
4563 // Check for viability and report error if casting an rvalue to a
4564 // life-time qualifier.
4565 if (castACTC == ACTC_retainable &&
4568 castType != castExprType) {
4569 const Type *DT = castType.getTypePtr();
4570 QualType QDT = castType;
4571 // We desugar some types but not others. We ignore those
4572 // that cannot happen in a cast; i.e. auto, and those which
4573 // should not be de-sugared; i.e typedef.
4574 if (const ParenType *PT = dyn_cast<ParenType>(DT))
4575 QDT = PT->desugar();
4576 else if (const TypeOfType *TP = dyn_cast<TypeOfType>(DT))
4577 QDT = TP->desugar();
4578 else if (const AttributedType *AT = dyn_cast<AttributedType>(DT))
4579 QDT = AT->desugar();
4580 if (QDT != castType &&
4582 if (Diagnose) {
4583 SourceLocation loc = (castRange.isValid() ? castRange.getBegin()
4584 : castExpr->getExprLoc());
4585 Diag(loc, diag::err_arc_nolifetime_behavior);
4586 }
4587 return ACR_error;
4588 }
4589 }
4590 return ACR_okay;
4591 }
4592
4593 // The life-time qualifier cast check above is all we need for ObjCWeak.
4594 // ObjCAutoRefCount has more restrictions on what is legal.
4595 if (!getLangOpts().ObjCAutoRefCount)
4596 return ACR_okay;
4597
4598 if (isAnyCLike(exprACTC) && isAnyCLike(castACTC)) return ACR_okay;
4599
4600 // Allow all of these types to be cast to integer types (but not
4601 // vice-versa).
4602 if (castACTC == ACTC_none && castType->isIntegralType(Context))
4603 return ACR_okay;
4604
4605 // Allow casts between pointers to lifetime types (e.g., __strong id*)
4606 // and pointers to void (e.g., cv void *). Casting from void* to lifetime*
4607 // must be explicit.
4608 // Allow conversions between pointers to lifetime types and coreFoundation
4609 // pointers too, but only when the conversions are explicit.
4610 // Allow conversions requested with a reinterpret_cast that converts an
4611 // expression of type T* to type U*.
4612 if (exprACTC == ACTC_indirectRetainable &&
4613 (castACTC == ACTC_voidPtr ||
4614 (castACTC == ACTC_coreFoundation && SemaRef.isCast(CCK)) ||
4615 (IsReinterpretCast && effCastType->isAnyPointerType())))
4616 return ACR_okay;
4617 if (castACTC == ACTC_indirectRetainable &&
4618 (((exprACTC == ACTC_voidPtr || exprACTC == ACTC_coreFoundation) &&
4619 SemaRef.isCast(CCK)) ||
4620 (IsReinterpretCast && castExprType->isAnyPointerType())))
4621 return ACR_okay;
4622
4623 switch (ARCCastChecker(Context, exprACTC, castACTC, false).Visit(castExpr)) {
4624 // For invalid casts, fall through.
4625 case ACC_invalid:
4626 break;
4627
4628 // Do nothing for both bottom and +0.
4629 case ACC_bottom:
4630 case ACC_plusZero:
4631 return ACR_okay;
4632
4633 // If the result is +1, consume it here.
4634 case ACC_plusOne:
4635 castExpr = ImplicitCastExpr::Create(Context, castExpr->getType(),
4636 CK_ARCConsumeObject, castExpr, nullptr,
4638 SemaRef.Cleanup.setExprNeedsCleanups(true);
4639 return ACR_okay;
4640 }
4641
4642 // If this is a non-implicit cast from id or block type to a
4643 // CoreFoundation type, delay complaining in case the cast is used
4644 // in an acceptable context.
4645 if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC) &&
4646 SemaRef.isCast(CCK))
4647 return ACR_unbridged;
4648
4649 // Issue a diagnostic about a missing @-sign when implicit casting a cstring
4650 // to 'NSString *', instead of falling through to report a "bridge cast"
4651 // diagnostic.
4652 if (castACTC == ACTC_retainable && exprACTC == ACTC_none &&
4653 CheckConversionToObjCLiteral(castType, castExpr, Diagnose))
4654 return ACR_error;
4655
4656 // Do not issue "bridge cast" diagnostic when implicit casting
4657 // a retainable object to a CF type parameter belonging to an audited
4658 // CF API function. Let caller issue a normal type mismatched diagnostic
4659 // instead.
4660 if ((!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
4661 castACTC != ACTC_coreFoundation) &&
4662 !(exprACTC == ACTC_voidPtr && castACTC == ACTC_retainable &&
4663 (Opc == BO_NE || Opc == BO_EQ))) {
4664 if (Diagnose)
4665 diagnoseObjCARCConversion(SemaRef, castRange, castType, castACTC,
4666 castExpr, castExpr, exprACTC, CCK);
4667 return ACR_error;
4668 }
4669 return ACR_okay;
4670}
4671
4672/// Given that we saw an expression with the ARCUnbridgedCastTy
4673/// placeholder type, complain bitterly.
4675 // We expect the spurious ImplicitCastExpr to already have been stripped.
4676 assert(!e->hasPlaceholderType(BuiltinType::ARCUnbridgedCast));
4677 CastExpr *realCast = cast<CastExpr>(e->IgnoreParens());
4678
4679 SourceRange castRange;
4680 QualType castType;
4682
4683 if (CStyleCastExpr *cast = dyn_cast<CStyleCastExpr>(realCast)) {
4684 castRange = SourceRange(cast->getLParenLoc(), cast->getRParenLoc());
4685 castType = cast->getTypeAsWritten();
4687 } else if (ExplicitCastExpr *cast = dyn_cast<ExplicitCastExpr>(realCast)) {
4688 castRange = cast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange();
4689 castType = cast->getTypeAsWritten();
4691 } else {
4692 llvm_unreachable("Unexpected ImplicitCastExpr");
4693 }
4694
4695 ARCConversionTypeClass castACTC =
4697
4698 Expr *castExpr = realCast->getSubExpr();
4700
4701 diagnoseObjCARCConversion(SemaRef, castRange, castType, castACTC, castExpr,
4702 realCast, ACTC_retainable, CCK);
4703}
4704
4705/// stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast
4706/// type, remove the placeholder cast.
4708 assert(e->hasPlaceholderType(BuiltinType::ARCUnbridgedCast));
4709 ASTContext &Context = getASTContext();
4710
4711 if (ParenExpr *pe = dyn_cast<ParenExpr>(e)) {
4712 Expr *sub = stripARCUnbridgedCast(pe->getSubExpr());
4713 return new (Context) ParenExpr(pe->getLParen(), pe->getRParen(), sub);
4714 } else if (UnaryOperator *uo = dyn_cast<UnaryOperator>(e)) {
4715 assert(uo->getOpcode() == UO_Extension);
4716 Expr *sub = stripARCUnbridgedCast(uo->getSubExpr());
4717 return UnaryOperator::Create(Context, sub, UO_Extension, sub->getType(),
4718 sub->getValueKind(), sub->getObjectKind(),
4719 uo->getOperatorLoc(), false,
4720 SemaRef.CurFPFeatureOverrides());
4721 } else if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {
4722 assert(!gse->isResultDependent());
4723 assert(!gse->isTypePredicate());
4724
4725 unsigned n = gse->getNumAssocs();
4726 SmallVector<Expr *, 4> subExprs;
4728 subExprs.reserve(n);
4729 subTypes.reserve(n);
4730 for (const GenericSelectionExpr::Association assoc : gse->associations()) {
4731 subTypes.push_back(assoc.getTypeSourceInfo());
4732 Expr *sub = assoc.getAssociationExpr();
4733 if (assoc.isSelected())
4734 sub = stripARCUnbridgedCast(sub);
4735 subExprs.push_back(sub);
4736 }
4737
4739 Context, gse->getGenericLoc(), gse->getControllingExpr(), subTypes,
4740 subExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
4741 gse->containsUnexpandedParameterPack(), gse->getResultIndex());
4742 } else {
4743 assert(isa<ImplicitCastExpr>(e) && "bad form of unbridged cast!");
4744 return cast<ImplicitCastExpr>(e)->getSubExpr();
4745 }
4746}
4747
4749 QualType exprType) {
4750 ASTContext &Context = getASTContext();
4751 QualType canCastType =
4752 Context.getCanonicalType(castType).getUnqualifiedType();
4753 QualType canExprType =
4754 Context.getCanonicalType(exprType).getUnqualifiedType();
4755 if (isa<ObjCObjectPointerType>(canCastType) &&
4756 castType.getObjCLifetime() == Qualifiers::OCL_Weak &&
4757 canExprType->isObjCObjectPointerType()) {
4758 if (const ObjCObjectPointerType *ObjT =
4759 canExprType->getAs<ObjCObjectPointerType>())
4760 if (const ObjCInterfaceDecl *ObjI = ObjT->getInterfaceDecl())
4761 return !ObjI->isArcWeakrefUnavailable();
4762 }
4763 return true;
4764}
4765
4766/// Look for an ObjCReclaimReturnedObject cast and destroy it.
4768 Expr *curExpr = e, *prevExpr = nullptr;
4769
4770 // Walk down the expression until we hit an implicit cast of kind
4771 // ARCReclaimReturnedObject or an Expr that is neither a Paren nor a Cast.
4772 while (true) {
4773 if (auto *pe = dyn_cast<ParenExpr>(curExpr)) {
4774 prevExpr = curExpr;
4775 curExpr = pe->getSubExpr();
4776 continue;
4777 }
4778
4779 if (auto *ce = dyn_cast<CastExpr>(curExpr)) {
4780 if (auto *ice = dyn_cast<ImplicitCastExpr>(ce))
4781 if (ice->getCastKind() == CK_ARCReclaimReturnedObject) {
4782 if (!prevExpr)
4783 return ice->getSubExpr();
4784 if (auto *pe = dyn_cast<ParenExpr>(prevExpr))
4785 pe->setSubExpr(ice->getSubExpr());
4786 else
4787 cast<CastExpr>(prevExpr)->setSubExpr(ice->getSubExpr());
4788 return e;
4789 }
4790
4791 prevExpr = curExpr;
4792 curExpr = ce->getSubExpr();
4793 continue;
4794 }
4795
4796 // Break out of the loop if curExpr is neither a Paren nor a Cast.
4797 break;
4798 }
4799
4800 return e;
4801}
4802
4804 ObjCBridgeCastKind Kind,
4805 SourceLocation BridgeKeywordLoc,
4806 TypeSourceInfo *TSInfo,
4807 Expr *SubExpr) {
4808 ASTContext &Context = getASTContext();
4809 ExprResult SubResult = SemaRef.UsualUnaryConversions(SubExpr);
4810 if (SubResult.isInvalid()) return ExprError();
4811 SubExpr = SubResult.get();
4812
4813 QualType T = TSInfo->getType();
4814 QualType FromType = SubExpr->getType();
4815
4816 CastKind CK;
4817
4818 bool MustConsume = false;
4819 if (T->isDependentType() || SubExpr->isTypeDependent()) {
4820 // Okay: we'll build a dependent expression type.
4821 CK = CK_Dependent;
4822 } else if (T->isObjCARCBridgableType() && FromType->isCARCBridgableType()) {
4823 // Casting CF -> id
4824 CK = (T->isBlockPointerType() ? CK_AnyPointerToBlockPointerCast
4825 : CK_CPointerToObjCPointerCast);
4826 switch (Kind) {
4827 case OBC_Bridge:
4828 break;
4829
4830 case OBC_BridgeRetained: {
4831 bool br = isKnownName("CFBridgingRelease");
4832 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4833 << 2
4834 << FromType
4835 << (T->isBlockPointerType()? 1 : 0)
4836 << T
4837 << SubExpr->getSourceRange()
4838 << Kind;
4839 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4840 << FixItHint::CreateReplacement(BridgeKeywordLoc, "__bridge");
4841 Diag(BridgeKeywordLoc, diag::note_arc_bridge_transfer)
4842 << FromType << br
4843 << FixItHint::CreateReplacement(BridgeKeywordLoc,
4844 br ? "CFBridgingRelease "
4845 : "__bridge_transfer ");
4846
4847 Kind = OBC_Bridge;
4848 break;
4849 }
4850
4851 case OBC_BridgeTransfer:
4852 // We must consume the Objective-C object produced by the cast.
4853 MustConsume = true;
4854 break;
4855 }
4856 } else if (T->isCARCBridgableType() && FromType->isObjCARCBridgableType()) {
4857 // Okay: id -> CF
4858 CK = CK_BitCast;
4859 switch (Kind) {
4860 case OBC_Bridge:
4861 // Reclaiming a value that's going to be __bridge-casted to CF
4862 // is very dangerous, so we don't do it.
4863 SubExpr = maybeUndoReclaimObject(SubExpr);
4864 break;
4865
4866 case OBC_BridgeRetained:
4867 // Produce the object before casting it.
4868 SubExpr = ImplicitCastExpr::Create(Context, FromType, CK_ARCProduceObject,
4869 SubExpr, nullptr, VK_PRValue,
4871 break;
4872
4873 case OBC_BridgeTransfer: {
4874 bool br = isKnownName("CFBridgingRetain");
4875 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4876 << (FromType->isBlockPointerType()? 1 : 0)
4877 << FromType
4878 << 2
4879 << T
4880 << SubExpr->getSourceRange()
4881 << Kind;
4882
4883 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4884 << FixItHint::CreateReplacement(BridgeKeywordLoc, "__bridge ");
4885 Diag(BridgeKeywordLoc, diag::note_arc_bridge_retained)
4886 << T << br
4887 << FixItHint::CreateReplacement(BridgeKeywordLoc,
4888 br ? "CFBridgingRetain " : "__bridge_retained");
4889
4890 Kind = OBC_Bridge;
4891 break;
4892 }
4893 }
4894 } else {
4895 Diag(LParenLoc, diag::err_arc_bridge_cast_incompatible)
4896 << FromType << T << Kind
4897 << SubExpr->getSourceRange()
4898 << TSInfo->getTypeLoc().getSourceRange();
4899 return ExprError();
4900 }
4901
4902 Expr *Result = new (Context) ObjCBridgedCastExpr(LParenLoc, Kind, CK,
4903 BridgeKeywordLoc,
4904 TSInfo, SubExpr);
4905
4906 if (MustConsume) {
4907 SemaRef.Cleanup.setExprNeedsCleanups(true);
4908 Result = ImplicitCastExpr::Create(Context, T, CK_ARCConsumeObject, Result,
4909 nullptr, VK_PRValue, FPOptionsOverride());
4910 }
4911
4912 return Result;
4913}
4914
4916 ObjCBridgeCastKind Kind,
4917 SourceLocation BridgeKeywordLoc,
4919 SourceLocation RParenLoc,
4920 Expr *SubExpr) {
4921 ASTContext &Context = getASTContext();
4922 TypeSourceInfo *TSInfo = nullptr;
4923 QualType T = SemaRef.GetTypeFromParser(Type, &TSInfo);
4924 if (Kind == OBC_Bridge)
4925 CheckTollFreeBridgeCast(T, SubExpr);
4926 if (!TSInfo)
4927 TSInfo = Context.getTrivialTypeSourceInfo(T, LParenLoc);
4928 return BuildObjCBridgedCast(LParenLoc, Kind, BridgeKeywordLoc, TSInfo,
4929 SubExpr);
4930}
4931
4933 IdentifierInfo *II) {
4934 SourceLocation Loc = Lookup.getNameLoc();
4935 ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl();
4936
4937 // Check for error condition which is already reported.
4938 if (!CurMethod)
4939 return DeclResult(true);
4940
4941 // There are two cases to handle here. 1) scoped lookup could have failed,
4942 // in which case we should look for an ivar. 2) scoped lookup could have
4943 // found a decl, but that decl is outside the current instance method (i.e.
4944 // a global variable). In these two cases, we do a lookup for an ivar with
4945 // this name, if the lookup sucedes, we replace it our current decl.
4946
4947 // If we're in a class method, we don't normally want to look for
4948 // ivars. But if we don't find anything else, and there's an
4949 // ivar, that's an error.
4950 bool IsClassMethod = CurMethod->isClassMethod();
4951
4952 bool LookForIvars;
4953 if (Lookup.empty())
4954 LookForIvars = true;
4955 else if (IsClassMethod)
4956 LookForIvars = false;
4957 else
4958 LookForIvars = (Lookup.isSingleResult() &&
4960 ObjCInterfaceDecl *IFace = nullptr;
4961 if (LookForIvars) {
4962 IFace = CurMethod->getClassInterface();
4963 ObjCInterfaceDecl *ClassDeclared;
4964 ObjCIvarDecl *IV = nullptr;
4965 if (IFace && (IV = IFace->lookupInstanceVariable(II, ClassDeclared))) {
4966 // Diagnose using an ivar in a class method.
4967 if (IsClassMethod) {
4968 Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName();
4969 return DeclResult(true);
4970 }
4971
4972 // Diagnose the use of an ivar outside of the declaring class.
4974 !declaresSameEntity(ClassDeclared, IFace) &&
4975 !getLangOpts().DebuggerSupport)
4976 Diag(Loc, diag::err_private_ivar_access) << IV->getDeclName();
4977
4978 // Success.
4979 return IV;
4980 }
4981 } else if (CurMethod->isInstanceMethod()) {
4982 // We should warn if a local variable hides an ivar.
4983 if (ObjCInterfaceDecl *IFace = CurMethod->getClassInterface()) {
4984 ObjCInterfaceDecl *ClassDeclared;
4985 if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) {
4986 if (IV->getAccessControl() != ObjCIvarDecl::Private ||
4987 declaresSameEntity(IFace, ClassDeclared))
4988 Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName();
4989 }
4990 }
4991 } else if (Lookup.isSingleResult() &&
4993 // If accessing a stand-alone ivar in a class method, this is an error.
4994 if (const ObjCIvarDecl *IV =
4995 dyn_cast<ObjCIvarDecl>(Lookup.getFoundDecl())) {
4996 Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName();
4997 return DeclResult(true);
4998 }
4999 }
5000
5001 // Didn't encounter an error, didn't find an ivar.
5002 return DeclResult(false);
5003}
5004
5006 IdentifierInfo *II,
5007 bool AllowBuiltinCreation) {
5008 // FIXME: Integrate this lookup step into LookupParsedName.
5009 DeclResult Ivar = LookupIvarInObjCMethod(Lookup, S, II);
5010 if (Ivar.isInvalid())
5011 return ExprError();
5012 if (Ivar.isUsable())
5013 return BuildIvarRefExpr(S, Lookup.getNameLoc(),
5014 cast<ObjCIvarDecl>(Ivar.get()));
5015
5016 if (Lookup.empty() && II && AllowBuiltinCreation)
5017 SemaRef.LookupBuiltin(Lookup);
5018
5019 // Sentinel value saying that we didn't do anything special.
5020 return ExprResult(false);
5021}
5022
5024 ObjCIvarDecl *IV) {
5025 ASTContext &Context = getASTContext();
5026 ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl();
5027 assert(CurMethod && CurMethod->isInstanceMethod() &&
5028 "should not reference ivar from this context");
5029
5030 ObjCInterfaceDecl *IFace = CurMethod->getClassInterface();
5031 assert(IFace && "should not reference ivar from this context");
5032
5033 // If we're referencing an invalid decl, just return this as a silent
5034 // error node. The error diagnostic was already emitted on the decl.
5035 if (IV->isInvalidDecl())
5036 return ExprError();
5037
5038 // Check if referencing a field with __attribute__((deprecated)).
5039 if (SemaRef.DiagnoseUseOfDecl(IV, Loc))
5040 return ExprError();
5041
5042 // FIXME: This should use a new expr for a direct reference, don't
5043 // turn this into Self->ivar, just return a BareIVarExpr or something.
5044 IdentifierInfo &II = Context.Idents.get("self");
5045 UnqualifiedId SelfName;
5046 SelfName.setImplicitSelfParam(&II);
5047 CXXScopeSpec SelfScopeSpec;
5048 SourceLocation TemplateKWLoc;
5049 ExprResult SelfExpr =
5050 SemaRef.ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, SelfName,
5051 /*HasTrailingLParen=*/false,
5052 /*IsAddressOfOperand=*/false);
5053 if (SelfExpr.isInvalid())
5054 return ExprError();
5055
5056 SelfExpr = SemaRef.DefaultLvalueConversion(SelfExpr.get());
5057 if (SelfExpr.isInvalid())
5058 return ExprError();
5059
5060 SemaRef.MarkAnyDeclReferenced(Loc, IV, true);
5061
5062 ObjCMethodFamily MF = CurMethod->getMethodFamily();
5063 if (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize &&
5064 !IvarBacksCurrentMethodAccessor(IFace, CurMethod, IV))
5065 Diag(Loc, diag::warn_direct_ivar_access) << IV->getDeclName();
5066
5067 ObjCIvarRefExpr *Result = new (Context)
5068 ObjCIvarRefExpr(IV, IV->getUsageType(SelfExpr.get()->getType()), Loc,
5069 IV->getLocation(), SelfExpr.get(), true, true);
5070
5072 if (!SemaRef.isUnevaluatedContext() &&
5073 !getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
5074 SemaRef.getCurFunction()->recordUseOfWeak(Result);
5075 }
5076 if (getLangOpts().ObjCAutoRefCount && !SemaRef.isUnevaluatedContext())
5077 if (const BlockDecl *BD = SemaRef.CurContext->getInnermostBlockDecl())
5078 SemaRef.ImplicitlyRetainedSelfLocs.push_back({Loc, BD});
5079
5080 return Result;
5081}
5082
5084 ExprResult &RHS,
5085 SourceLocation QuestionLoc) {
5086 ASTContext &Context = getASTContext();
5087 QualType LHSTy = LHS.get()->getType();
5088 QualType RHSTy = RHS.get()->getType();
5089
5090 // Handle things like Class and struct objc_class*. Here we case the result
5091 // to the pseudo-builtin, because that will be implicitly cast back to the
5092 // redefinition type if an attempt is made to access its fields.
5093 if (LHSTy->isObjCClassType() &&
5094 (Context.hasSameType(RHSTy, Context.getObjCClassRedefinitionType()))) {
5095 RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy,
5096 CK_CPointerToObjCPointerCast);
5097 return LHSTy;
5098 }
5099 if (RHSTy->isObjCClassType() &&
5100 (Context.hasSameType(LHSTy, Context.getObjCClassRedefinitionType()))) {
5101 LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy,
5102 CK_CPointerToObjCPointerCast);
5103 return RHSTy;
5104 }
5105 // And the same for struct objc_object* / id
5106 if (LHSTy->isObjCIdType() &&
5107 (Context.hasSameType(RHSTy, Context.getObjCIdRedefinitionType()))) {
5108 RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy,
5109 CK_CPointerToObjCPointerCast);
5110 return LHSTy;
5111 }
5112 if (RHSTy->isObjCIdType() &&
5113 (Context.hasSameType(LHSTy, Context.getObjCIdRedefinitionType()))) {
5114 LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy,
5115 CK_CPointerToObjCPointerCast);
5116 return RHSTy;
5117 }
5118 // And the same for struct objc_selector* / SEL
5119 if (Context.isObjCSelType(LHSTy) &&
5120 (Context.hasSameType(RHSTy, Context.getObjCSelRedefinitionType()))) {
5121 RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy, CK_BitCast);
5122 return LHSTy;
5123 }
5124 if (Context.isObjCSelType(RHSTy) &&
5125 (Context.hasSameType(LHSTy, Context.getObjCSelRedefinitionType()))) {
5126 LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy, CK_BitCast);
5127 return RHSTy;
5128 }
5129 // Check constraints for Objective-C object pointers types.
5130 if (LHSTy->isObjCObjectPointerType() && RHSTy->isObjCObjectPointerType()) {
5131
5132 if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
5133 // Two identical object pointer types are always compatible.
5134 return LHSTy;
5135 }
5136 const ObjCObjectPointerType *LHSOPT =
5137 LHSTy->castAs<ObjCObjectPointerType>();
5138 const ObjCObjectPointerType *RHSOPT =
5139 RHSTy->castAs<ObjCObjectPointerType>();
5140 QualType compositeType = LHSTy;
5141
5142 // If both operands are interfaces and either operand can be
5143 // assigned to the other, use that type as the composite
5144 // type. This allows
5145 // xxx ? (A*) a : (B*) b
5146 // where B is a subclass of A.
5147 //
5148 // Additionally, as for assignment, if either type is 'id'
5149 // allow silent coercion. Finally, if the types are
5150 // incompatible then make sure to use 'id' as the composite
5151 // type so the result is acceptable for sending messages to.
5152
5153 // FIXME: Consider unifying with 'areComparableObjCPointerTypes'.
5154 // It could return the composite type.
5155 if (!(compositeType = Context.areCommonBaseCompatible(LHSOPT, RHSOPT))
5156 .isNull()) {
5157 // Nothing more to do.
5158 } else if (Context.canAssignObjCInterfaces(LHSOPT, RHSOPT)) {
5159 compositeType = RHSOPT->isObjCBuiltinType() ? RHSTy : LHSTy;
5160 } else if (Context.canAssignObjCInterfaces(RHSOPT, LHSOPT)) {
5161 compositeType = LHSOPT->isObjCBuiltinType() ? LHSTy : RHSTy;
5162 } else if ((LHSOPT->isObjCQualifiedIdType() ||
5163 RHSOPT->isObjCQualifiedIdType()) &&
5164 Context.ObjCQualifiedIdTypesAreCompatible(LHSOPT, RHSOPT,
5165 true)) {
5166 // Need to handle "id<xx>" explicitly.
5167 // GCC allows qualified id and any Objective-C type to devolve to
5168 // id. Currently localizing to here until clear this should be
5169 // part of ObjCQualifiedIdTypesAreCompatible.
5170 compositeType = Context.getObjCIdType();
5171 } else if (LHSTy->isObjCIdType() || RHSTy->isObjCIdType()) {
5172 compositeType = Context.getObjCIdType();
5173 } else {
5174 Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)
5175 << LHSTy << RHSTy << LHS.get()->getSourceRange()
5176 << RHS.get()->getSourceRange();
5177 QualType incompatTy = Context.getObjCIdType();
5178 LHS = SemaRef.ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast);
5179 RHS = SemaRef.ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast);
5180 return incompatTy;
5181 }
5182 // The object pointer types are compatible.
5183 LHS = SemaRef.ImpCastExprToType(LHS.get(), compositeType, CK_BitCast);
5184 RHS = SemaRef.ImpCastExprToType(RHS.get(), compositeType, CK_BitCast);
5185 return compositeType;
5186 }
5187 // Check Objective-C object pointer types and 'void *'
5188 if (LHSTy->isVoidPointerType() && RHSTy->isObjCObjectPointerType()) {
5189 if (getLangOpts().ObjCAutoRefCount) {
5190 // ARC forbids the implicit conversion of object pointers to 'void *',
5191 // so these types are not compatible.
5192 Diag(QuestionLoc, diag::err_cond_voidptr_arc)
5193 << LHSTy << RHSTy << LHS.get()->getSourceRange()
5194 << RHS.get()->getSourceRange();
5195 LHS = RHS = true;
5196 return QualType();
5197 }
5198 QualType lhptee = LHSTy->castAs<PointerType>()->getPointeeType();
5200 QualType destPointee =
5201 Context.getQualifiedType(lhptee, rhptee.getQualifiers());
5202 QualType destType = Context.getPointerType(destPointee);
5203 // Add qualifiers if necessary.
5204 LHS = SemaRef.ImpCastExprToType(LHS.get(), destType, CK_NoOp);
5205 // Promote to void*.
5206 RHS = SemaRef.ImpCastExprToType(RHS.get(), destType, CK_BitCast);
5207 return destType;
5208 }
5209 if (LHSTy->isObjCObjectPointerType() && RHSTy->isVoidPointerType()) {
5210 if (getLangOpts().ObjCAutoRefCount) {
5211 // ARC forbids the implicit conversion of object pointers to 'void *',
5212 // so these types are not compatible.
5213 Diag(QuestionLoc, diag::err_cond_voidptr_arc)
5214 << LHSTy << RHSTy << LHS.get()->getSourceRange()
5215 << RHS.get()->getSourceRange();
5216 LHS = RHS = true;
5217 return QualType();
5218 }
5220 QualType rhptee = RHSTy->castAs<PointerType>()->getPointeeType();
5221 QualType destPointee =
5222 Context.getQualifiedType(rhptee, lhptee.getQualifiers());
5223 QualType destType = Context.getPointerType(destPointee);
5224 // Add qualifiers if necessary.
5225 RHS = SemaRef.ImpCastExprToType(RHS.get(), destType, CK_NoOp);
5226 // Promote to void*.
5227 LHS = SemaRef.ImpCastExprToType(LHS.get(), destType, CK_BitCast);
5228 return destType;
5229 }
5230 return QualType();
5231}
5232
5234 bool Diagnose) {
5235 if (!getLangOpts().ObjC)
5236 return false;
5237
5238 const ObjCObjectPointerType *PT = DstType->getAs<ObjCObjectPointerType>();
5239 if (!PT)
5240 return false;
5241 const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();
5242
5243 // Ignore any parens, implicit casts (should only be
5244 // array-to-pointer decays), and not-so-opaque values. The last is
5245 // important for making this trigger for property assignments.
5246 Expr *SrcExpr = Exp->IgnoreParenImpCasts();
5247 if (OpaqueValueExpr *OV = dyn_cast<OpaqueValueExpr>(SrcExpr))
5248 if (OV->getSourceExpr())
5249 SrcExpr = OV->getSourceExpr()->IgnoreParenImpCasts();
5250
5251 if (auto *SL = dyn_cast<StringLiteral>(SrcExpr)) {
5252 if (!PT->isObjCIdType() && !(ID && ID->getIdentifier()->isStr("NSString")))
5253 return false;
5254 if (!SL->isOrdinary())
5255 return false;
5256
5257 if (Diagnose) {
5258 Diag(SL->getBeginLoc(), diag::err_missing_atsign_prefix)
5259 << /*string*/ 0 << FixItHint::CreateInsertion(SL->getBeginLoc(), "@");
5260 Exp = BuildObjCStringLiteral(SL->getBeginLoc(), SL).get();
5261 }
5262 return true;
5263 }
5264
5265 if ((isa<IntegerLiteral>(SrcExpr) || isa<CharacterLiteral>(SrcExpr) ||
5266 isa<FloatingLiteral>(SrcExpr) || isa<ObjCBoolLiteralExpr>(SrcExpr) ||
5267 isa<CXXBoolLiteralExpr>(SrcExpr)) &&
5270 if (!ID || !ID->getIdentifier()->isStr("NSNumber"))
5271 return false;
5272 if (Diagnose) {
5273 Diag(SrcExpr->getBeginLoc(), diag::err_missing_atsign_prefix)
5274 << /*number*/ 1
5275 << FixItHint::CreateInsertion(SrcExpr->getBeginLoc(), "@");
5276 Expr *NumLit =
5277 BuildObjCNumericLiteral(SrcExpr->getBeginLoc(), SrcExpr).get();
5278 if (NumLit)
5279 Exp = NumLit;
5280 }
5281 return true;
5282 }
5283
5284 return false;
5285}
5286
5287/// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals.
5289 tok::TokenKind Kind) {
5290 assert((Kind == tok::kw___objc_yes || Kind == tok::kw___objc_no) &&
5291 "Unknown Objective-C Boolean value!");
5292 ASTContext &Context = getASTContext();
5293 QualType BoolT = Context.ObjCBuiltinBoolTy;
5294 if (!Context.getBOOLDecl()) {
5295 LookupResult Result(SemaRef, &Context.Idents.get("BOOL"), OpLoc,
5297 if (SemaRef.LookupName(Result, SemaRef.getCurScope()) &&
5298 Result.isSingleResult()) {
5299 NamedDecl *ND = Result.getFoundDecl();
5300 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(ND))
5301 Context.setBOOLDecl(TD);
5302 }
5303 }
5304 if (Context.getBOOLDecl())
5305 BoolT = Context.getBOOLType();
5306 return new (Context)
5307 ObjCBoolLiteralExpr(Kind == tok::kw___objc_yes, BoolT, OpLoc);
5308}
5309
5312 SourceLocation RParen) {
5313 ASTContext &Context = getASTContext();
5314 auto FindSpecVersion =
5315 [&](StringRef Platform,
5316 const llvm::Triple::OSType &OS) -> std::optional<VersionTuple> {
5317 auto Spec = llvm::find_if(AvailSpecs, [&](const AvailabilitySpec &Spec) {
5318 return Spec.getPlatform() == Platform;
5319 });
5320 // Transcribe the "ios" availability check to "maccatalyst" when compiling
5321 // for "maccatalyst" if "maccatalyst" is not specified.
5322 if (Spec == AvailSpecs.end() && Platform == "maccatalyst") {
5323 Spec = llvm::find_if(AvailSpecs, [&](const AvailabilitySpec &Spec) {
5324 return Spec.getPlatform() == "ios";
5325 });
5326 }
5327 // Use "anyappleos" spec if no platform-specific spec is found and the
5328 // target is an Apple OS.
5329 if (Spec == AvailSpecs.end()) {
5330 // Check if this OS is a Darwin/Apple OS.
5331 const llvm::Triple &Triple = Context.getTargetInfo().getTriple();
5332 if (Triple.isOSDarwin()) {
5333 Spec = llvm::find_if(AvailSpecs, [&](const AvailabilitySpec &Spec) {
5334 return Spec.getPlatform() == "anyappleos";
5335 });
5336 }
5337 }
5338 if (Spec == AvailSpecs.end())
5339 return std::nullopt;
5340
5341 return llvm::Triple::getCanonicalVersionForOS(
5342 OS, Spec->getVersion(),
5343 llvm::Triple::isValidVersionForOS(OS, Spec->getVersion()));
5344 };
5345
5346 VersionTuple Version;
5347 if (auto MaybeVersion =
5348 FindSpecVersion(Context.getTargetInfo().getPlatformName(),
5349 Context.getTargetInfo().getTriple().getOS()))
5350 Version = *MaybeVersion;
5351
5352 // The use of `@available` in the enclosing context should be analyzed to
5353 // warn when it's used inappropriately (i.e. not if(@available)).
5354 if (FunctionScopeInfo *Context = SemaRef.getCurFunctionAvailabilityContext())
5355 Context->HasPotentialAvailabilityViolations = true;
5356
5357 return new (Context)
5358 ObjCAvailabilityCheckExpr(Version, AtLoc, RParen, Context.BoolTy);
5359}
5360
5361/// Prepare a conversion of the given expression to an ObjC object
5362/// pointer type.
5364 QualType type = E.get()->getType();
5365 if (type->isObjCObjectPointerType()) {
5366 return CK_BitCast;
5367 } else if (type->isBlockPointerType()) {
5368 SemaRef.maybeExtendBlockObject(E);
5369 return CK_BlockPointerToObjCPointerCast;
5370 } else {
5371 assert(type->isPointerType());
5372 return CK_CPointerToObjCPointerCast;
5373 }
5374}
5375
5377 FromE = FromE->IgnoreParenImpCasts();
5378 switch (FromE->getStmtClass()) {
5379 default:
5380 break;
5381 case Stmt::ObjCStringLiteralClass:
5382 // "string literal"
5383 return LK_String;
5384 case Stmt::ObjCArrayLiteralClass:
5385 // "array literal"
5386 return LK_Array;
5387 case Stmt::ObjCDictionaryLiteralClass:
5388 // "dictionary literal"
5389 return LK_Dictionary;
5390 case Stmt::BlockExprClass:
5391 return LK_Block;
5392 case Stmt::ObjCBoxedExprClass: {
5393 Expr *Inner = cast<ObjCBoxedExpr>(FromE)->getSubExpr()->IgnoreParens();
5394 switch (Inner->getStmtClass()) {
5395 case Stmt::IntegerLiteralClass:
5396 case Stmt::FloatingLiteralClass:
5397 case Stmt::CharacterLiteralClass:
5398 case Stmt::ObjCBoolLiteralExprClass:
5399 case Stmt::CXXBoolLiteralExprClass:
5400 // "numeric literal"
5401 return LK_Numeric;
5402 case Stmt::ImplicitCastExprClass: {
5403 CastKind CK = cast<CastExpr>(Inner)->getCastKind();
5404 // Boolean literals can be represented by implicit casts.
5405 if (CK == CK_IntegralToBoolean || CK == CK_IntegralCast)
5406 return LK_Numeric;
5407 break;
5408 }
5409 default:
5410 break;
5411 }
5412 return LK_Boxed;
5413 }
5414 }
5415 return LK_None;
5416}
Defines the clang::ASTContext interface.
static StringRef bytes(const std::vector< T, Allocator > &v)
Defines enum values for all the target-independent builtin functions.
llvm::MachO::Target Target
Definition MachO.h:51
#define SM(sm)
Defines the clang::Preprocessor interface.
static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr, bool &HadTheAttribute, bool warn)
static ObjCMethodDecl * getNSNumberFactoryMethod(SemaObjC &S, SourceLocation Loc, QualType NumberType, bool isLiteral=false, SourceRange R=SourceRange())
Retrieve the NSNumber factory method that should be used to create an Objective-C literal for the giv...
static QualType stripObjCInstanceType(ASTContext &Context, QualType T)
static void diagnoseObjCARCConversion(Sema &S, SourceRange castRange, QualType castType, ARCConversionTypeClass castACTC, Expr *castExpr, Expr *realCast, ARCConversionTypeClass exprACTC, CheckedConversionKind CCK)
static ObjCInterfaceDecl * LookupObjCInterfaceDeclForLiteral(Sema &S, SourceLocation Loc, SemaObjC::ObjCLiteralKind LiteralKind)
Looks up ObjCInterfaceDecl of a given NSClassIdKindKind.
static ObjCMethodDecl * findMethodInCurrentClass(Sema &S, Selector Sel)
static void checkCocoaAPI(Sema &S, const ObjCMessageExpr *Msg)
static bool CheckObjCNumberExpressionIsConstant(Sema &S, Expr *Number)
static ObjCMethodDecl * LookupDirectMethodInGlobalPool(Sema &S, Selector Sel, bool &onlyDirect, bool &anyDirect)
static Expr * maybeUndoReclaimObject(Expr *e)
Look for an ObjCReclaimReturnedObject cast and destroy it.
static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr, bool &HadTheAttribute, bool warn)
static void CheckObjCDictionaryLiteralDuplicateKeys(Sema &S, ObjCDictionaryLiteral *Literal)
Check for duplicate keys in an ObjC dictionary literal.
static bool ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl, SourceLocation Loc, SemaObjC::ObjCLiteralKind LiteralKind)
Validates ObjCInterfaceDecl availability.
static NSAPI::NSClassIdKindKind ClassKindFromLiteralKind(SemaObjC::ObjCLiteralKind LiteralKind)
Maps ObjCLiteralKind to NSClassIdKindKind.
static bool isAnyCLike(ARCConversionTypeClass ACTC)
static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc, ObjCMethodDecl *Method, SourceLocation LParenLoc, SourceLocation RParenLoc, bool WarnMultipleSelectors)
static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S, SourceLocation AtLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, ObjCMethodDecl *Method, ObjCMethodList &MethList)
static void applyCocoaAPICheck(Sema &S, const ObjCMessageExpr *Msg, unsigned DiagID, bool(*refactor)(const ObjCMessageExpr *, const NSAPI &, edit::Commit &))
static ObjCMethodDecl * LookupDirectMethodInMethodList(Sema &S, Selector Sel, ObjCMethodList &MethList, bool &onlyDirect, bool &anyDirect)
static ObjCBridgeRelatedAttr * ObjCBridgeRelatedAttrFromType(QualType T, TypedefNameDecl *&TDNDecl)
static T * getObjCBridgeAttr(const TypedefType *TD)
static ARCConversionTypeClass classifyTypeForARCConversion(QualType type)
static bool isAnyRetainable(ARCConversionTypeClass ACTC)
static void RemoveSelectorFromWarningCache(SemaObjC &S, Expr *Arg)
ARCConversionTypeClass
@ ACTC_voidPtr
void* might be a normal C type, or it might a CF type.
@ ACTC_retainable
id, void (^)()
@ ACTC_coreFoundation
struct A*
@ ACTC_indirectRetainable
id*, id***, void (^*)(),
@ ACTC_none
int, void, struct A
static QualType getBaseMessageSendResultType(Sema &S, QualType ReceiverType, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage)
Determine the result type of a message send based on the receiver type, method, and the kind of messa...
static const ObjCMethodDecl * findExplicitInstancetypeDeclarer(const ObjCMethodDecl *MD, QualType instancetype)
Look for an ObjC method whose result type exactly matches the given type.
static void DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S, ObjCMethodDecl *Method, Selector Sel, Expr **Args, unsigned NumArgs)
Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...
static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M)
static bool validateBoxingMethod(Sema &S, SourceLocation Loc, const ObjCInterfaceDecl *Class, Selector Sel, const ObjCMethodDecl *Method)
Emits an error if the given method does not exist, or if the return type is not an Objective-C object...
static void checkFoundationAPI(Sema &S, SourceLocation Loc, const ObjCMethodDecl *Method, ArrayRef< Expr * > Args, QualType ReceiverType, bool IsClassObjectCall)
static void addFixitForObjCARCConversion(Sema &S, DiagBuilderT &DiagB, CheckedConversionKind CCK, SourceLocation afterLParen, QualType castType, Expr *castExpr, Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName)
static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element, QualType T, bool ArrayLiteral=false)
Check that the given expression is a valid element of an Objective-C collection literal.
This file declares semantic analysis for Objective-C.
static QualType getPointeeType(const MemRegion *R)
Defines the clang::TypeLoc interface and its subclasses.
__device__ __2f16 b
__device__ __2f16 float __ockl_bool s
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:226
SourceManager & getSourceManager()
Definition ASTContext.h:859
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
bool QIdProtocolsAdoptObjCObjectProtocols(QualType QT, ObjCInterfaceDecl *IDecl)
QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in QT's qualified-id protocol list adopt...
IdentifierTable & Idents
Definition ASTContext.h:798
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl)
ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's protocol list adopt all protocols in Q...
PtrTy get() const
Definition Ownership.h:171
bool isInvalid() const
Definition Ownership.h:167
bool isUsable() const
Definition Ownership.h:169
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition TypeBase.h:3772
ArraySizeModifier getSizeModifier() const
Definition TypeBase.h:3786
QualType getElementType() const
Definition TypeBase.h:3784
unsigned getIndexTypeCVRQualifiers() const
Definition TypeBase.h:3794
One specifier in an @available expression.
StringRef getPlatform() const
VersionTuple getVersion() const
Expr * getRHS() const
Definition Expr.h:4093
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4689
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Definition Expr.h:3972
Abstract class common to all of the C++ "named"/"keyword" casts.
Definition ExprCXX.h:376
Represents a C++ nested-name-specifier or a global scope specifier.
Definition DeclSpec.h:74
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition Expr.h:3129
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition Expr.h:3679
CastKind getCastKind() const
Definition Expr.h:3723
Expr * getSubExpr()
Definition Expr.h:3729
Stmt * body_back()
Definition Stmt.h:1809
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Definition Expr.h:4426
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Definition Expr.h:4421
Represents the canonical version of C arrays with a specified constant size.
Definition TypeBase.h:3810
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1449
Simple template class for restricting typo correction candidates to ones having a single Decl* of the...
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1273
ValueDecl * getDecl()
Definition Expr.h:1341
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition DeclBase.h:593
bool isInvalidDecl() const
Definition DeclBase.h:588
SourceLocation getLocation() const
Definition DeclBase.h:439
bool isDefinedOutsideFunctionOrMethod() const
isDefinedOutsideFunctionOrMethod - This predicate returns true if this scoped decl is defined outside...
Definition DeclBase.h:949
DeclContext * getDeclContext()
Definition DeclBase.h:448
SourceLocation getBeginLoc() const LLVM_READONLY
Definition DeclBase.h:431
TranslationUnitDecl * getTranslationUnitDecl()
Definition DeclBase.cpp:531
bool hasAttr() const
Definition DeclBase.h:577
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
bool isIdentifier() const
Predicate functions for querying what type of name this is.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Definition Diagnostic.h:959
ExplicitCastExpr - An explicit cast written in the source code.
Definition Expr.h:3931
This represents one expression.
Definition Expr.h:112
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
Expr * IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY
Skip past any parentheses and casts which do not change the value (including ptr->int casts of the sa...
Definition Expr.cpp:3117
@ SE_AllowSideEffects
Allow any unmodeled side effect.
Definition Expr.h:677
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition Expr.cpp:3095
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition Expr.h:177
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
Definition Expr.h:447
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition Expr.h:194
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...
Definition Expr.cpp:3107
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition Expr.cpp:3090
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
bool isObjCSelfExpr() const
Check if this expression is the ObjC 'self' implicit parameter.
Definition Expr.cpp:4211
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3086
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
@ NPC_ValueDependentIsNull
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
Definition Expr.h:834
@ NPC_NeverValueDependent
Specifies that the expression should never be value-dependent.
Definition Expr.h:830
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
Definition Expr.h:838
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Definition Expr.h:454
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3070
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
Definition Expr.cpp:4068
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition Expr.cpp:277
QualType getType() const
Definition Expr.h:144
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
Definition Expr.h:526
static ExprValueKind getValueKindForType(QualType T)
getValueKindForType - Given a formal return or parameter type, give its value kind.
Definition Expr.h:437
Represents difference between two FPOptions values.
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, CharSourceRange FromRange, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code from FromRange at a specific location.
Definition Diagnostic.h:116
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
Definition Diagnostic.h:140
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
Definition Diagnostic.h:129
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
Definition Diagnostic.h:103
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition Decl.cpp:3763
QualType getReturnType() const
Definition Decl.h:2860
Represents a C11 generic selection.
Definition Expr.h:6181
AssociationTy< false > Association
Definition Expr.h:6414
static GenericSelectionExpr * Create(const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, ArrayRef< TypeSourceInfo * > AssocTypes, ArrayRef< Expr * > AssocExprs, SourceLocation DefaultLoc, SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack, unsigned ResultIndex)
Create a non-result-dependent generic selection expression accepting an expression predicate.
Definition Expr.cpp:4716
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Definition Expr.cpp:2073
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
Describes an entity that is being initialized.
static InitializedEntity InitializeTemporary(QualType Type)
Create the initialization entity for a temporary.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
static bool isAsciiIdentifierContinueChar(char c, const LangOptions &LangOpts)
Returns true if the given character could appear in an identifier.
Definition Lexer.cpp:1148
Represents the results of name lookup.
Definition Lookup.h:147
bool empty() const
Return true if no decls were found.
Definition Lookup.h:362
SourceLocation getNameLoc() const
Gets the location of the identifier.
Definition Lookup.h:666
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
Definition Lookup.h:569
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
Definition Lookup.h:331
NSClassIdKindKind
Definition NSAPI.h:29
@ ClassId_NSDictionary
Definition NSAPI.h:34
@ ClassId_NSValue
Definition NSAPI.h:39
@ ClassId_NSObject
Definition NSAPI.h:30
@ ClassId_NSNumber
Definition NSAPI.h:36
@ ClassId_NSArray
Definition NSAPI.h:32
@ ClassId_NSString
Definition NSAPI.h:31
@ NSDict_dictionaryWithObjectsForKeysCount
Definition NSAPI.h:101
@ NSArr_arrayWithObjectsCount
Definition NSAPI.h:77
This represents a decl that may have a name.
Definition Decl.h:274
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Definition Decl.h:317
static ObjCArrayLiteral * Create(const ASTContext &C, ArrayRef< Expr * > Elements, QualType T, ObjCMethodDecl *Method, bool ExpressibleAsConstantInitializer, SourceRange SR)
Definition ExprObjC.cpp:42
A runtime availability query.
Definition ExprObjC.h:1734
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
Definition ExprObjC.h:119
ObjCBoxedExpr - used for generalized expression boxing.
Definition ExprObjC.h:159
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers,...
Definition ExprObjC.h:1674
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition DeclObjC.h:2545
ObjCContainerDecl - Represents a container for method declarations.
Definition DeclObjC.h:948
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
Definition DeclObjC.cpp:90
ObjCPropertyDecl * FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyDeclaration - Finds declaration of the property given its name in 'PropertyId' and return...
Definition DeclObjC.cpp:247
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition ExprObjC.h:342
static ObjCDictionaryLiteral * Create(const ASTContext &C, ArrayRef< ObjCDictionaryElement > VK, bool HasPackExpansions, QualType T, ObjCMethodDecl *Method, bool ExpressibleAsConstantInitializer, SourceRange SR)
Definition ExprObjC.cpp:85
ObjCEncodeExpr, used for @encode in Objective-C.
Definition ExprObjC.h:441
Represents an ObjC class declaration.
Definition DeclObjC.h:1154
ObjCMethodDecl * lookupClassMethod(Selector Sel) const
Lookup a class method for a given selector.
Definition DeclObjC.h:1852
static ObjCInterfaceDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation atLoc, const IdentifierInfo *Id, ObjCTypeParamList *typeParamList, ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc=SourceLocation(), bool isInternal=false)
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
Definition DeclObjC.cpp:634
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
Definition DeclObjC.h:1847
ObjCMethodDecl * lookupPrivateClassMethod(const Selector &Sel)
Definition DeclObjC.h:1862
ObjCMethodDecl * getCategoryClassMethod(Selector Sel) const
ObjCMethodDecl * lookupPrivateMethod(const Selector &Sel, bool Instance=true) const
Lookup a method in the classes implementation hierarchy.
Definition DeclObjC.cpp:753
ObjCMethodDecl * lookupMethod(Selector Sel, bool isInstance, bool shallowCategoryLookup=false, bool followSuper=true, const ObjCCategoryDecl *C=nullptr) const
lookupMethod - This method returns an instance/class method by looking in the class,...
Definition DeclObjC.cpp:696
ObjCInterfaceDecl * getSuperClass() const
Definition DeclObjC.cpp:349
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
Definition DeclObjC.h:1810
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
Definition TypeBase.h:7993
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
Definition Type.cpp:953
ObjCIvarDecl - Represents an ObjC instance variable.
Definition DeclObjC.h:1952
AccessControl getAccessControl() const
Definition DeclObjC.h:2000
QualType getUsageType(QualType objectType) const
Retrieve the type of this instance variable when viewed as a member of a specific object type.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition ExprObjC.h:580
An expression that sends a message to the given Objective-C object or class.
Definition ExprObjC.h:971
static ObjCMessageExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, QualType SuperType, Selector Sel, ArrayRef< SourceLocation > SelLocs, ObjCMethodDecl *Method, ArrayRef< Expr * > Args, SourceLocation RBracLoc, bool isImplicit)
Create a message send to super.
Definition ExprObjC.cpp:183
Selector getSelector() const
Definition ExprObjC.cpp:301
const ObjCMethodDecl * getMethodDecl() const
Definition ExprObjC.h:1395
ObjCMethodDecl - Represents an instance or class method declaration.
Definition DeclObjC.h:140
ImplicitParamDecl * getSelfDecl() const
Definition DeclObjC.h:418
ArrayRef< ParmVarDecl * > parameters() const
Definition DeclObjC.h:373
bool isPropertyAccessor() const
Definition DeclObjC.h:436
void getOverriddenMethods(SmallVectorImpl< const ObjCMethodDecl * > &Overridden) const
Return overridden methods for the given Method.
static ObjCMethodDecl * Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl, bool isInstance=true, bool isVariadic=false, bool isPropertyAccessor=false, bool isSynthesizedAccessorStub=false, bool isImplicitlyDeclared=false, bool isDefined=false, ObjCImplementationControl impControl=ObjCImplementationControl::None, bool HasRelatedResultType=false)
Definition DeclObjC.cpp:849
const ObjCPropertyDecl * findPropertyDecl(bool CheckOverrides=true) const
Returns the property associated with this method's selector.
void setMethodParams(ASTContext &C, ArrayRef< ParmVarDecl * > Params, ArrayRef< SourceLocation > SelLocs={})
Sets the method's parameters and selector source locations.
Definition DeclObjC.cpp:941
bool hasRelatedResultType() const
Determine whether this method has a result type that is related to the message receiver's type.
Definition DeclObjC.h:256
SourceLocation getBeginLoc() const LLVM_READONLY
Definition DeclObjC.h:282
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Definition DeclObjC.cpp:868
Selector getSelector() const
Definition DeclObjC.h:327
bool isInstanceMethod() const
Definition DeclObjC.h:426
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
QualType getReturnType() const
Definition DeclObjC.h:329
bool isClassMethod() const
Definition DeclObjC.h:434
ObjCInterfaceDecl * getClassInterface()
bool isGlobalAllocation() const
Definition ExprObjC.h:65
Represents a pointer to an Objective C object.
Definition TypeBase.h:8049
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
Definition TypeBase.h:8124
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
Definition TypeBase.h:8107
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
Definition TypeBase.h:8061
ObjCInterfaceDecl * getInterfaceDecl() const
If this pointer points to an Objective @interface type, gets the declaration for that interface.
Definition TypeBase.h:8101
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
Definition Type.cpp:1854
qual_range quals() const
Definition TypeBase.h:8168
Represents one property declaration in an Objective-C interface.
Definition DeclObjC.h:731
ObjCMethodDecl * getGetterMethodDecl() const
Definition DeclObjC.h:901
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
Definition ExprObjC.h:648
ObjCPropertyDecl * getExplicitProperty() const
Definition ExprObjC.h:737
ObjCMethodDecl * getImplicitPropertyGetter() const
Definition ExprObjC.h:742
bool isExplicitProperty() const
Definition ExprObjC.h:735
Represents an Objective-C protocol declaration.
Definition DeclObjC.h:2084
bool hasDefinition() const
Determine whether this protocol has a definition.
Definition DeclObjC.h:2238
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
Definition DeclObjC.h:2250
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
ObjCProtocolExpr used for protocol expression in Objective-C.
Definition ExprObjC.h:536
bool hasConstantEmptyCollections() const
bool hasConstantCFBooleans() const
ObjCSelectorExpr used for @selector in Objective-C.
Definition ExprObjC.h:486
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition ExprObjC.h:84
ObjCSubscriptRefExpr - used for array and dictionary subscripting.
Definition ExprObjC.h:870
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition Expr.h:1181
ParenExpr - This represents a parenthesized expression, e.g.
Definition Expr.h:2185
Sugar for parentheses used when specifying types.
Definition TypeBase.h:3352
Represents a parameter to a function.
Definition Decl.h:1805
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Definition Decl.cpp:2958
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3378
QualType getPointeeType() const
Definition TypeBase.h:3388
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
Definition Expr.h:6851
A (possibly-)qualified type.
Definition TypeBase.h:937
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
Definition TypeBase.h:1302
QualType withConst() const
Definition TypeBase.h:1165
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8431
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition TypeBase.h:8471
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
Definition TypeBase.h:1444
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition TypeBase.h:8616
QualType getCanonicalType() const
Definition TypeBase.h:8483
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition TypeBase.h:8525
QualType substObjCTypeArgs(ASTContext &ctx, ArrayRef< QualType > typeArgs, ObjCSubstitutionContext context) const
Substitute type arguments for the Objective-C type parameters used in the subject type.
Definition Type.cpp:1661
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition TypeBase.h:1338
@ OCL_None
There is no lifetime qualification on this type.
Definition TypeBase.h:350
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition TypeBase.h:364
Base for LValueReferenceType and RValueReferenceType.
Definition TypeBase.h:3623
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
bool isInObjcMethodScope() const
isInObjcMethodScope - Return true if this scope is, or is contained in, an Objective-C method body.
Definition Scope.h:459
static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)
Return the default setter selector for the given identifier.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
ObjCMethodFamily getMethodFamily() const
Derive the conventional family of this method.
bool isUnarySelector() const
ObjCStringFormatFamily getStringFormatFamily() const
unsigned getNumArgs() const
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition SemaBase.cpp:33
ASTContext & getASTContext() const
Definition SemaBase.cpp:9
Sema & SemaRef
Definition SemaBase.h:40
const LangOptions & getLangOpts() const
Definition SemaBase.cpp:11
DiagnosticsEngine & getDiagnostics() const
Definition SemaBase.cpp:10
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Definition SemaBase.cpp:61
ObjCMessageKind getObjCMessageKind(Scope *S, IdentifierInfo *Name, SourceLocation NameLoc, bool IsSuper, bool HasTrailingDot, ParsedType &ReceiverType)
ObjCMethodDecl * ValueWithBytesObjCTypeMethod
The declaration of the valueWithBytes:objCType: method.
Definition SemaObjC.h:618
ExprResult BuildObjCDictionaryLiteral(SourceRange SR, MutableArrayRef< ObjCDictionaryElement > Elements)
ExprResult HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, Expr *BaseExpr, SourceLocation OpLoc, DeclarationName MemberName, SourceLocation MemberLoc, SourceLocation SuperLoc, QualType SuperType, bool Super)
HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an objective C interface.
ExprResult BuildInstanceMessage(Expr *Receiver, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args, bool isImplicit=false)
Build an Objective-C instance message expression.
const ObjCMethodDecl * SelectorsForTypoCorrection(Selector Sel, QualType ObjectType=QualType())
ExprResult ParseObjCSelectorExpression(Selector Sel, SourceLocation AtLoc, SourceLocation SelLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, bool WarnMultipleSelectors)
ParseObjCSelectorExpression - Build selector expression for @selector.
ExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args, bool isImplicit=false)
Build an Objective-C class message expression.
ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number)
BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the numeric literal expression.
bool AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, SourceRange R, bool receiverIdOrClass, SmallVectorImpl< ObjCMethodDecl * > &Methods)
ObjCMethodDecl * LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupInstanceMethodInGlobalPool - Returns the method and warns if there are multiple signatures.
Definition SemaObjC.h:855
ExprResult ActOnObjCBridgedCast(Scope *S, SourceLocation LParenLoc, ObjCBridgeCastKind Kind, SourceLocation BridgeKeywordLoc, ParsedType Type, SourceLocation RParenLoc, Expr *SubExpr)
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, TypeSourceInfo *EncodedTypeInfo, SourceLocation RParenLoc)
bool CheckObjCBridgeRelatedConversions(SourceLocation Loc, QualType DestType, QualType SrcType, Expr *&SrcExpr, bool Diagnose=true)
ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements)
ObjCInterfaceDecl * NSArrayDecl
The declaration of the Objective-C NSArray class.
Definition SemaObjC.h:621
ExprResult ActOnClassPropertyRefExpr(const IdentifierInfo &receiverName, const IdentifierInfo &propertyName, SourceLocation receiverNameLoc, SourceLocation propertyNameLoc)
void CheckObjCCircularContainer(ObjCMessageExpr *Message)
Check whether receiver is mutable ObjC container which attempts to add itself into the container.
ObjCInterfaceDecl * getObjCInterfaceDecl(const IdentifierInfo *&Id, SourceLocation IdLoc, bool TypoCorrection=false)
Look for an Objective-C class in the translation unit.
ObjCMethodDecl * LookupMethodInObjectType(Selector Sel, QualType Ty, bool IsInstance)
LookupMethodInType - Look up a method in an ObjCObjectType.
bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, ObjCMethodDecl *Method, ObjCIvarDecl *IV)
IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is an ivar synthesized for 'Meth...
ExprResult BuildClassMessageImplicit(QualType ReceiverType, bool isSuperReceiver, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
ObjCInterfaceDecl * NSNumberDecl
The declaration of the Objective-C NSNumber class.
Definition SemaObjC.h:594
void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr)
ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr)
BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the '@' prefixed parenthesized expression.
ObjCInterfaceDecl * NSValueDecl
The declaration of the Objective-C NSValue class.
Definition SemaObjC.h:597
Selector RespondsToSelectorSel
will hold 'respondsToSelector:'
Definition SemaObjC.h:636
bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, const ObjCMethodDecl *PrevMethod, MethodMatchStrategy strategy=MMS_strict)
MatchTwoMethodDeclarations - Checks if two methods' type match and returns true, or false,...
bool CheckMessageArgumentTypes(const Expr *Receiver, QualType ReceiverType, MultiExprArg Args, Selector Sel, ArrayRef< SourceLocation > SelectorLocs, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage, SourceLocation lbrac, SourceLocation rbrac, SourceRange RecRange, QualType &ReturnType, ExprValueKind &VK)
CheckMessageArgumentTypes - Check types in an Obj-C message send.
ObjCInterfaceDecl * NSStringDecl
The declaration of the Objective-C NSString class.
Definition SemaObjC.h:609
llvm::MapVector< Selector, SourceLocation > ReferencedSelectors
Method selectors used in a @selector expression.
Definition SemaObjC.h:209
ObjCMethodDecl * LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupFactoryMethodInGlobalPool - Returns the method and warns if there are multiple signatures.
Definition SemaObjC.h:864
ObjCMethodDecl * StringWithUTF8StringMethod
The declaration of the stringWithUTF8String: method.
Definition SemaObjC.h:615
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall)
Check whether the given method, which must be in the 'init' family, is a valid member of that family.
QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, SourceLocation QuestionLoc)
FindCompositeObjCPointerType - Helper method to find composite type of two objective-c pointer types ...
ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S)
ObjCInterfaceDecl * NSDictionaryDecl
The declaration of the Objective-C NSDictionary class.
Definition SemaObjC.h:627
ObjCMethodDecl * ArrayWithObjectsMethod
The declaration of the arrayWithObjects:count: method.
Definition SemaObjC.h:624
ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc, SourceLocation EncodeLoc, SourceLocation LParenLoc, ParsedType Ty, SourceLocation RParenLoc)
QualType QIDNSCopying
id<NSCopying> type.
Definition SemaObjC.h:633
bool CheckObjCString(Expr *Arg)
CheckObjCString - Checks that the argument to the builtin CFString constructor is correct Note: It mi...
ExprResult ActOnClassMessage(Scope *S, ParsedType Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr)
bool CheckConversionToObjCLiteral(QualType DstType, Expr *&SrcExpr, bool Diagnose=true)
ObjCMethodDecl * tryCaptureObjCSelf(SourceLocation Loc)
Try to capture an implicit reference to 'self'.
ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, ArrayRef< Expr * > Strings)
ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc, bool Value)
ObjCMethodDecl * DictionaryWithObjectsMethod
The declaration of the dictionaryWithObjects:forKeys:count: method.
Definition SemaObjC.h:630
QualType NSStringPointer
Pointer to NSString type (NSString *).
Definition SemaObjC.h:612
ExprResult BuildObjCBridgedCast(SourceLocation LParenLoc, ObjCBridgeCastKind Kind, SourceLocation BridgeKeywordLoc, TypeSourceInfo *TSInfo, Expr *SubExpr)
ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Find the protocol with the given name, if any.
QualType NSNumberPointer
Pointer to NSNumber type (NSNumber *).
Definition SemaObjC.h:600
DeclResult LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S, IdentifierInfo *II)
The parser has read a name in, and Sema has detected that we're currently inside an ObjC method.
ObjCMethodDecl * NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods]
The Objective-C NSNumber methods used to create NSNumber literals.
Definition SemaObjC.h:606
GlobalMethodPool MethodPool
Method Pool - allows efficient lookup when typechecking messages to "id".
Definition SemaObjC.h:220
QualType getMessageSendResultType(const Expr *Receiver, QualType ReceiverType, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage)
Determine the result of a message send expression based on the type of the receiver,...
ExprResult ParseObjCProtocolExpression(IdentifierInfo *ProtocolName, SourceLocation AtLoc, SourceLocation ProtoLoc, SourceLocation LParenLoc, SourceLocation ProtoIdLoc, SourceLocation RParenLoc)
ParseObjCProtocolExpression - Build protocol expression for @protocol.
ExprResult BuildInstanceMessageImplicit(Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
void checkRetainCycles(ObjCMessageExpr *msg)
checkRetainCycles - Check whether an Objective-C message send might create an obvious retain cycle.
ObjCMessageKind
Describes the kind of message expression indicated by a message send that starts with an identifier.
Definition SemaObjC.h:708
@ ObjCClassMessage
The message is a class message, and the identifier is a type name.
Definition SemaObjC.h:715
@ ObjCInstanceMessage
The message is an instance message.
Definition SemaObjC.h:712
@ ObjCSuperMessage
The message is sent to 'super'.
Definition SemaObjC.h:710
ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S, IdentifierInfo *II, bool AllowBuiltinCreation=false)
The parser has read a name in, and Sema has detected that we're currently inside an ObjC method.
QualType NSValuePointer
Pointer to NSValue type (NSValue *).
Definition SemaObjC.h:603
void EmitRelatedResultTypeNote(const Expr *E)
If the given expression involves a message send to a method with a related result type,...
ExprResult ActOnInstanceMessage(Scope *S, Expr *Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx)
ExprResult BuildIvarRefExpr(Scope *S, SourceLocation Loc, ObjCIvarDecl *IV)
ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
CastKind PrepareCastToObjCObjectPointer(ExprResult &E)
Prepare a conversion of the given expression to an ObjC object pointer type.
bool CollectMultipleMethodsInGlobalPool(Selector Sel, SmallVectorImpl< ObjCMethodDecl * > &Methods, bool InstanceFirst, bool CheckTheOther, const ObjCObjectType *TypeBound=nullptr)
We first select the type of the method: Instance or Factory, then collect all methods with that type.
bool checkObjCBridgeRelatedComponents(SourceLocation Loc, QualType DestType, QualType SrcType, ObjCInterfaceDecl *&RelatedClass, ObjCMethodDecl *&ClassMethod, ObjCMethodDecl *&InstanceMethod, TypedefNameDecl *&TDNDecl, bool CfToNs, bool Diagnose=true)
void EmitRelatedResultTypeNoteForReturn(QualType destType)
Given that we had incompatible pointer types in a return statement, check whether we're in a method w...
void diagnoseARCUnbridgedCast(Expr *e)
Given that we saw an expression with the ARCUnbridgedCastTy placeholder type, complain bitterly.
ObjCMethodDecl * LookupMethodInQualifiedType(Selector Sel, const ObjCObjectPointerType *OPT, bool IsInstance)
LookupMethodInQualifiedType - Lookups up a method in protocol qualifier list of a qualified objective...
ARCConversionResult CheckObjCConversion(SourceRange castRange, QualType castType, Expr *&op, CheckedConversionKind CCK, bool Diagnose=true, bool DiagnoseCFAudited=false, BinaryOperatorKind Opc=BO_PtrMemD, bool IsReinterpretCast=false)
Checks for invalid conversions and casts between retainable pointers and other pointer kinds for ARC ...
bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, CastKind &Kind)
bool CheckObjCARCUnavailableWeakConversion(QualType castType, QualType ExprType)
bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, ArrayRef< const Expr * > Args)
Expr * stripARCUnbridgedCast(Expr *e)
stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast type, remove the placeholder cast.
ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, Expr *IndexExpr, ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod)
Build an ObjC subscript pseudo-object expression, given that that's supported by the runtime.
bool isSelfExpr(Expr *RExpr)
Private Helper predicate to check for 'self'.
ExprResult ActOnObjCAvailabilityCheckExpr(llvm::ArrayRef< AvailabilitySpec > AvailSpecs, SourceLocation AtLoc, SourceLocation RParen)
bool isKnownName(StringRef name)
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
Definition SemaObjC.h:591
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:868
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition Sema.h:9402
bool FormatStringHasSArg(const StringLiteral *FExpr)
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Look up a name, looking for a single declaration.
ASTContext & Context
Definition Sema.h:1304
SemaObjC & ObjC()
Definition Sema.h:1514
ASTContext & getASTContext() const
Definition Sema.h:939
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
Definition Sema.cpp:1716
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
Definition Sema.cpp:84
const LangOptions & getLangOpts() const
Definition Sema.h:932
const LangOptions & LangOpts
Definition Sema.h:1302
ExprResult DefaultLvalueConversion(Expr *E)
Definition SemaExpr.cpp:643
static bool isCast(CheckedConversionKind CCK)
Definition Sema.h:2568
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
SourceManager & getSourceManager() const
Definition Sema.h:937
bool makeUnavailableInSystemHeader(SourceLocation loc, UnavailableAttr::ImplicitReason reason)
makeUnavailableInSystemHeader - There is an error in the current context.
Definition Sema.cpp:631
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
Definition Sema.h:1263
SourceManager & SourceMgr
Definition Sema.h:1307
DiagnosticsEngine & Diags
Definition Sema.h:1306
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
A trivial tuple used to represent a source range.
bool isInvalid() const
SourceLocation getEnd() const
SourceLocation getBegin() const
CompoundStmt * getSubStmt()
Definition Expr.h:4615
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
SourceLocation getEndLoc() const LLVM_READONLY
Definition Stmt.cpp:367
StmtClass getStmtClass() const
Definition Stmt.h:1494
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:355
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1802
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Expr.h:1976
tokloc_iterator tokloc_begin() const
Definition Expr.h:1968
tokloc_iterator tokloc_end() const
Definition Expr.h:1972
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, ArrayRef< SourceLocation > Locs)
This is the "fully general" constructor that allows representation of strings formed from one or more...
Definition Expr.cpp:1188
StringRef getString() const
Definition Expr.h:1870
bool isOrdinary() const
Definition Expr.h:1919
The top declaration context.
Definition Decl.h:105
Represents a declaration of a type.
Definition Decl.h:3528
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:3562
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
Definition TypeLoc.h:154
A container of type source information.
Definition TypeBase.h:8402
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition TypeLoc.h:267
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8413
The base class of the type hierarchy.
Definition TypeBase.h:1866
bool isBlockPointerType() const
Definition TypeBase.h:8688
const ObjCObjectPointerType * getAsObjCQualifiedClassType() const
Definition Type.cpp:1897
bool isVoidType() const
Definition TypeBase.h:9034
bool isBooleanType() const
Definition TypeBase.h:9171
const ObjCObjectPointerType * getAsObjCQualifiedIdType() const
Definition Type.cpp:1887
bool isObjCBuiltinType() const
Definition TypeBase.h:8898
bool isVoidPointerType() const
Definition Type.cpp:714
bool isObjCARCBridgableType() const
Determine whether the given type T is a "bridgable" Objective-C type, which is either an Objective-C ...
Definition Type.cpp:5396
bool isPointerType() const
Definition TypeBase.h:8668
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition TypeBase.h:9078
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9328
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
Definition Type.cpp:1915
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
Definition Type.cpp:2121
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:754
bool canHaveNullability(bool ResultIfUnknown=true) const
Determine whether the given type can have a nullability specifier applied to it, i....
Definition Type.cpp:5111
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2832
bool isCARCBridgableType() const
Determine whether the given type T is a "bridgeable" C type.
Definition Type.cpp:5401
bool isObjCIdType() const
Definition TypeBase.h:8880
bool isObjCClassOrClassKindOfType() const
Whether the type is Objective-C 'Class' or a __kindof type of an Class type, e.g.,...
Definition Type.cpp:836
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition TypeBase.h:9314
bool isObjCObjectPointerType() const
Definition TypeBase.h:8847
bool isObjCQualifiedClassType() const
Definition TypeBase.h:8874
bool isObjCClassType() const
Definition TypeBase.h:8886
std::optional< ArrayRef< QualType > > getObjCSubstitutions(const DeclContext *dc) const
Retrieve the set of substitutions required when accessing a member of the Objective-C receiver type t...
Definition Type.cpp:1692
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2971
const ObjCObjectType * getAsObjCInterfaceType() const
Definition Type.cpp:1907
bool isAnyPointerType() const
Definition TypeBase.h:8676
bool isObjCIdOrObjectKindOfType(const ASTContext &ctx, const ObjCObjectType *&bound) const
Whether the type is Objective-C 'id' or a __kindof type of an object type, e.g., __kindof NSView * or...
Definition Type.cpp:809
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9261
bool isRecordType() const
Definition TypeBase.h:8795
bool isObjCRetainableType() const
Definition Type.cpp:5368
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
Definition Type.cpp:5098
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition Decl.h:3682
Base class for declarations which introduce a typedef-name.
Definition Decl.h:3577
QualType getUnderlyingType() const
Definition Decl.h:3632
TypedefNameDecl * getDecl() const
Definition TypeBase.h:6202
Simple class containing the result of Sema::CorrectTypo.
DeclClass * getCorrectionDeclAs() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2247
Expr * getSubExpr() const
Definition Expr.h:2288
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
Definition Expr.cpp:5151
Represents a C++ unqualified-id that has been parsed.
Definition DeclSpec.h:1033
void setImplicitSelfParam(const IdentifierInfo *Id)
Specify that this unqualified-id is an implicit 'self' parameter.
Definition DeclSpec.h:1235
void setType(QualType newType)
Definition Decl.h:724
QualType getType() const
Definition Decl.h:723
bool isCommitable() const
Definition Commit.h:68
edit_iterator edit_begin() const
Definition Commit.h:121
SmallVectorImpl< Edit >::const_iterator edit_iterator
Definition Commit.h:119
edit_iterator edit_end() const
Definition Commit.h:122
Retains information about a function, method, or block that is currently being parsed.
Definition ScopeInfo.h:104
bool ObjCIsDesignatedInit
True when this is a method marked as a designated initializer.
Definition ScopeInfo.h:153
bool ObjCWarnForNoInitDelegation
This starts true for a secondary initializer method and will be set to false if there is an invocatio...
Definition ScopeInfo.h:167
bool ObjCIsSecondaryInit
True when this is an initializer method not marked as a designated initializer within a class that ha...
Definition ScopeInfo.h:163
bool ObjCWarnForNoDesignatedInitChain
This starts true for a method marked as designated initializer and will be set to false if there is a...
Definition ScopeInfo.h:158
Defines the clang::TargetInfo interface.
Definition SPIR.cpp:47
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
constexpr Variable var(Literal L)
Returns the variable of L.
Definition CNFFormula.h:64
bool rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
bool followsCreateRule(const FunctionDecl *FD)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Definition TokenKinds.h:25
RangeSelector merge(RangeSelector First, RangeSelector Second)
Selects the merge of the two ranges, i.e.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ CPlusPlus
@ Ambiguous
Name lookup results in an ambiguity; use getAmbiguityKind to figure out what kind of ambiguity we hav...
Definition Lookup.h:64
@ NotFound
No entity found met the criteria.
Definition Lookup.h:41
@ FoundOverloaded
Name lookup found a set of overloaded functions that met the criteria.
Definition Lookup.h:54
@ Found
Name lookup found a single declaration that met the criteria.
Definition Lookup.h:50
@ FoundUnresolvedValue
Name lookup found an unresolvable value declaration and cannot yet complete.
Definition Lookup.h:59
@ NotFoundInCurrentInstantiation
No entity found met the criteria within the current instantiation,, but there were dependent base cla...
Definition Lookup.h:46
NullabilityKind
Describes the nullability of a particular type.
Definition Specifiers.h:348
@ Nullable
Values of this type can be null.
Definition Specifiers.h:352
@ NonNull
Values of this type can never be null.
Definition Specifiers.h:350
@ OK_ObjCProperty
An Objective-C property is a logical field of an Objective-C object which is read and written via Obj...
Definition Specifiers.h:161
@ OK_ObjCSubscript
An Objective-C array/dictionary subscripting which reads an object or writes at the subscripted array...
Definition Specifiers.h:166
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
ActionResult< Decl * > DeclResult
Definition Ownership.h:255
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ SC_None
Definition Specifiers.h:250
ObjCMethodFamily
A family of Objective-C methods.
@ OMF_performSelector
@ OMF_None
No particular method family.
MutableArrayRef< Expr * > MultiExprArg
Definition Ownership.h:259
@ Parameter
The parameter type of a method or function.
Definition TypeBase.h:908
@ Result
The result type of a method or function.
Definition TypeBase.h:905
ObjCBridgeCastKind
The kind of bridging performed by the Objective-C bridge cast.
@ OBC_Bridge
Bridging via __bridge, which does nothing but reinterpret the bits.
@ OBC_BridgeTransfer
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC.
@ OBC_BridgeRetained
Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.
ExprResult ExprError()
Definition Ownership.h:265
CastKind
CastKind - The kind of operation required for a conversion.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition Specifiers.h:132
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition Specifiers.h:135
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition Specifiers.h:139
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition DeclBase.h:1288
U cast(CodeGen::Address addr)
Definition Address.h:327
@ None
The alignment was not explicit in code.
Definition ASTContext.h:179
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
Definition Ownership.h:230
@ None
No keyword precedes the qualified type name.
Definition TypeBase.h:5977
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5967
ActionResult< Expr * > ExprResult
Definition Ownership.h:249
CheckedConversionKind
The kind of conversion being performed.
Definition Sema.h:438
@ Implicit
An implicit conversion.
Definition Sema.h:440
@ CStyleCast
A C-style cast.
Definition Sema.h:442
@ ForBuiltinOverloadedOp
A conversion for an operand of a builtin overloaded operator.
Definition Sema.h:448
@ OtherCast
A cast other than a C-style cast.
Definition Sema.h:446
@ FunctionalCast
A functional-style cast.
Definition Sema.h:444
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
EvalResult is a struct with detailed info about an evaluated expression.
Definition Expr.h:648
An element in an Objective-C dictionary literal.
Definition ExprObjC.h:295
a linked list of methods with the same selector name but different signatures.
ObjCMethodDecl * getMethod() const
ObjCMethodList * getNext() const
CharSourceRange getFileRange(SourceManager &SM) const
Definition Commit.cpp:30
SourceLocation OrigLoc
Definition Commit.h:40
CharSourceRange getInsertFromRange(SourceManager &SM) const
Definition Commit.cpp:35