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