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