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