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