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