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