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