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