1 //===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements semantic analysis for Objective-C expressions.
11 //===----------------------------------------------------------------------===//
13 #include "clang/AST/ASTContext.h"
14 #include "clang/AST/Availability.h"
15 #include "clang/AST/DeclObjC.h"
16 #include "clang/AST/ExprObjC.h"
17 #include "clang/AST/StmtVisitor.h"
18 #include "clang/AST/TypeLoc.h"
19 #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
20 #include "clang/Basic/Builtins.h"
21 #include "clang/Basic/TargetInfo.h"
22 #include "clang/Edit/Commit.h"
23 #include "clang/Edit/Rewriters.h"
24 #include "clang/Lex/Preprocessor.h"
25 #include "clang/Sema/Initialization.h"
26 #include "clang/Sema/Lookup.h"
27 #include "clang/Sema/Scope.h"
28 #include "clang/Sema/ScopeInfo.h"
29 #include "clang/Sema/SemaObjC.h"
30 #include "llvm/Support/ConvertUTF.h"
33 using namespace clang
;
37 ExprResult
SemaObjC::ParseObjCStringLiteral(SourceLocation
*AtLocs
,
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]);
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
;
50 SmallVector
<SourceLocation
, 8> StrLocs
;
52 for (Expr
*E
: Strings
) {
53 S
= cast
<StringLiteral
>(E
);
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();
63 StrBuf
+= S
->getString();
65 // Get the locations of the string tokens.
66 StrLocs
.append(S
->tokloc_begin(), S
->tokloc_end());
69 // Create the aggregate string with the appropriate content and location
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,
75 CAT
->getSizeModifier(), CAT
->getIndexTypeCVRQualifiers());
76 S
= StringLiteral::Create(Context
, StrBuf
, StringLiteralKind::Ordinary
,
77 /*Pascal=*/false, StrTy
, &StrLocs
[0],
81 return BuildObjCStringLiteral(AtLocs
[0], S
);
84 ExprResult
SemaObjC::BuildObjCStringLiteral(SourceLocation AtLoc
,
86 ASTContext
&Context
= getASTContext();
87 // Verify that this composite string is acceptable for ObjC strings.
88 if (CheckObjCString(S
))
91 // Initialize the constant string interface lazily. This assumes
92 // the NSString interface is seen in this translation unit. Note: We
93 // don't use NSConstantString, since the runtime team considers this
94 // interface private (even though it appears in the header files).
95 QualType Ty
= Context
.getObjCConstantStringInterface();
97 Ty
= Context
.getObjCObjectPointerType(Ty
);
98 } else if (getLangOpts().NoConstantCFStrings
) {
99 IdentifierInfo
*NSIdent
=nullptr;
100 std::string
StringClass(getLangOpts().ObjCConstantStringClass
);
102 if (StringClass
.empty())
103 NSIdent
= &Context
.Idents
.get("NSConstantString");
105 NSIdent
= &Context
.Idents
.get(StringClass
);
107 NamedDecl
*IF
= SemaRef
.LookupSingleName(SemaRef
.TUScope
, NSIdent
, AtLoc
,
108 Sema::LookupOrdinaryName
);
109 if (ObjCInterfaceDecl
*StrIF
= dyn_cast_or_null
<ObjCInterfaceDecl
>(IF
)) {
110 Context
.setObjCConstantStringInterface(StrIF
);
111 Ty
= Context
.getObjCConstantStringInterface();
112 Ty
= Context
.getObjCObjectPointerType(Ty
);
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();
121 IdentifierInfo
*NSIdent
= NSAPIObj
->getNSClassId(NSAPI::ClassId_NSString
);
122 NamedDecl
*IF
= SemaRef
.LookupSingleName(SemaRef
.TUScope
, NSIdent
, AtLoc
,
123 Sema::LookupOrdinaryName
);
124 if (ObjCInterfaceDecl
*StrIF
= dyn_cast_or_null
<ObjCInterfaceDecl
>(IF
)) {
125 Context
.setObjCConstantStringInterface(StrIF
);
126 Ty
= Context
.getObjCConstantStringInterface();
127 Ty
= Context
.getObjCObjectPointerType(Ty
);
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();
135 ObjCInterfaceDecl
*NSStringIDecl
=
136 ObjCInterfaceDecl::Create (Context
,
137 Context
.getTranslationUnitDecl(),
138 SourceLocation(), NSIdent
,
139 nullptr, nullptr, SourceLocation());
140 Ty
= Context
.getObjCInterfaceType(NSStringIDecl
);
141 Context
.setObjCNSStringType(Ty
);
143 Ty
= Context
.getObjCObjectPointerType(Ty
);
147 return new (Context
) ObjCStringLiteral(S
, Ty
, AtLoc
);
150 /// Emits an error if the given method does not exist, or if the return
151 /// type is not an Objective-C object.
152 static bool validateBoxingMethod(Sema
&S
, SourceLocation Loc
,
153 const ObjCInterfaceDecl
*Class
,
154 Selector Sel
, const ObjCMethodDecl
*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();
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
)
166 S
.Diag(Method
->getLocation(), diag::note_objc_literal_method_return
)
174 /// Maps ObjCLiteralKind to NSClassIdKindKind
175 static NSAPI::NSClassIdKindKind
176 ClassKindFromLiteralKind(SemaObjC::ObjCLiteralKind LiteralKind
) {
177 switch (LiteralKind
) {
178 case SemaObjC::LK_Array
:
179 return NSAPI::ClassId_NSArray
;
180 case SemaObjC::LK_Dictionary
:
181 return NSAPI::ClassId_NSDictionary
;
182 case SemaObjC::LK_Numeric
:
183 return NSAPI::ClassId_NSNumber
;
184 case SemaObjC::LK_String
:
185 return NSAPI::ClassId_NSString
;
186 case SemaObjC::LK_Boxed
:
187 return NSAPI::ClassId_NSValue
;
189 // there is no corresponding matching
190 // between LK_None/LK_Block and NSClassIdKindKind
191 case SemaObjC::LK_Block
:
192 case SemaObjC::LK_None
:
195 llvm_unreachable("LiteralKind can't be converted into a ClassKind");
198 /// Validates ObjCInterfaceDecl availability.
199 /// ObjCInterfaceDecl, used to create ObjC literals, should be defined
200 /// if clang not in a debugger mode.
202 ValidateObjCLiteralInterfaceDecl(Sema
&S
, ObjCInterfaceDecl
*Decl
,
204 SemaObjC::ObjCLiteralKind LiteralKind
) {
206 NSAPI::NSClassIdKindKind Kind
= ClassKindFromLiteralKind(LiteralKind
);
207 IdentifierInfo
*II
= S
.ObjC().NSAPIObj
->getNSClassId(Kind
);
208 S
.Diag(Loc
, diag::err_undeclared_objc_literal_class
)
209 << II
->getName() << LiteralKind
;
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
);
221 /// Looks up ObjCInterfaceDecl of a given NSClassIdKindKind.
222 /// Used to create ObjC literals, such as NSDictionary (@{}),
223 /// NSArray (@[]) and Boxed Expressions (@())
224 static ObjCInterfaceDecl
*
225 LookupObjCInterfaceDeclForLiteral(Sema
&S
, SourceLocation Loc
,
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
,
230 Sema::LookupOrdinaryName
);
231 ObjCInterfaceDecl
*ID
= dyn_cast_or_null
<ObjCInterfaceDecl
>(IF
);
232 if (!ID
&& S
.getLangOpts().DebuggerObjCLiteral
) {
233 ASTContext
&Context
= S
.Context
;
234 TranslationUnitDecl
*TU
= Context
.getTranslationUnitDecl();
235 ID
= ObjCInterfaceDecl::Create (Context
, TU
, SourceLocation(), II
,
236 nullptr, nullptr, SourceLocation());
239 if (!ValidateObjCLiteralInterfaceDecl(S
, ID
, Loc
, LiteralKind
)) {
246 /// Retrieve the NSNumber factory method that should be used to create
247 /// an Objective-C literal for the given type.
248 static ObjCMethodDecl
*getNSNumberFactoryMethod(SemaObjC
&S
, SourceLocation Loc
,
250 bool isLiteral
= false,
251 SourceRange R
= SourceRange()) {
252 std::optional
<NSAPI::NSNumberLiteralMethodKind
> Kind
=
253 S
.NSAPIObj
->getNSNumberFactoryMethodKind(NumberType
);
257 S
.Diag(Loc
, diag::err_invalid_nsnumber_type
)
263 // If we already looked up this method, we're done.
264 if (S
.NSNumberLiteralMethods
[*Kind
])
265 return S
.NSNumberLiteralMethods
[*Kind
];
267 Selector Sel
= S
.NSAPIObj
->getNSNumberLiteralSelector(*Kind
,
270 ASTContext
&CX
= S
.SemaRef
.Context
;
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
) {
276 LookupObjCInterfaceDeclForLiteral(S
.SemaRef
, Loc
, SemaObjC::LK_Numeric
);
277 if (!S
.NSNumberDecl
) {
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
);
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);
303 ParmVarDecl::Create(S
.SemaRef
.Context
, Method
, SourceLocation(),
304 SourceLocation(), &CX
.Idents
.get("value"),
305 NumberType
, /*TInfo=*/nullptr, SC_None
, nullptr);
306 Method
->setMethodParams(S
.SemaRef
.Context
, value
, {});
309 if (!validateBoxingMethod(S
.SemaRef
, Loc
, S
.NSNumberDecl
, Sel
, Method
))
312 // Note: if the parameter type is out-of-line, we'll catch it later in the
313 // implicit conversion.
315 S
.NSNumberLiteralMethods
[*Kind
] = Method
;
319 /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the
320 /// numeric literal expression. Type of the expression will be "NSNumber *".
321 ExprResult
SemaObjC::BuildObjCNumericLiteral(SourceLocation AtLoc
,
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()) {
330 case CharacterLiteralKind::Ascii
:
331 case CharacterLiteralKind::UTF8
:
332 NumberType
= Context
.CharTy
;
335 case CharacterLiteralKind::Wide
:
336 NumberType
= Context
.getWideCharType();
339 case CharacterLiteralKind::UTF16
:
340 NumberType
= Context
.Char16Ty
;
343 case CharacterLiteralKind::UTF32
:
344 NumberType
= Context
.Char32Ty
;
349 // Look for the appropriate method within NSNumber.
350 // Construct the literal.
351 SourceRange
NR(Number
->getSourceRange());
352 ObjCMethodDecl
*Method
= getNSNumberFactoryMethod(*this, AtLoc
, NumberType
,
357 // Convert the number to the type that the parameter expects.
358 ParmVarDecl
*ParamDecl
= Method
->parameters()[0];
359 InitializedEntity Entity
= InitializedEntity::InitializeParameter(Context
,
361 ExprResult ConvertedNumber
=
362 SemaRef
.PerformCopyInitialization(Entity
, SourceLocation(), Number
);
363 if (ConvertedNumber
.isInvalid())
365 Number
= ConvertedNumber
.get();
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())));
372 ExprResult
SemaObjC::ActOnObjCBoolLiteral(SourceLocation AtLoc
,
373 SourceLocation ValueLoc
, bool Value
) {
374 ASTContext
&Context
= getASTContext();
376 if (getLangOpts().CPlusPlus
) {
377 Inner
= SemaRef
.ActOnCXXBoolLiteral(ValueLoc
,
378 Value
? tok::kw_true
: tok::kw_false
);
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
);
387 return BuildObjCNumericLiteral(AtLoc
, Inner
.get());
390 /// Check that the given expression is a valid element of an Objective-C
391 /// collection literal.
392 static ExprResult
CheckObjCCollectionLiteralElement(Sema
&S
, Expr
*Element
,
394 bool ArrayLiteral
= false) {
395 // If the expression is type-dependent, there's nothing for us to do.
396 if (Element
->isTypeDependent())
399 ExprResult Result
= S
.CheckPlaceholderExpr(Element
);
400 if (Result
.isInvalid())
402 Element
= Result
.get();
404 // In C++, check for an implicit conversion to an Objective-C object pointer
406 if (S
.getLangOpts().CPlusPlus
&& Element
->getType()->isRecordType()) {
407 InitializedEntity Entity
408 = InitializedEntity::InitializeParameter(S
.Context
, T
,
410 InitializationKind Kind
= InitializationKind::CreateCopy(
411 Element
->getBeginLoc(), SourceLocation());
412 InitializationSequence
Seq(S
, Entity
, Kind
, Element
);
414 return Seq
.Perform(S
, Entity
, Kind
, Element
);
417 Expr
*OrigElement
= Element
;
419 // Perform lvalue-to-rvalue conversion.
420 Result
= S
.DefaultLvalueConversion(Element
);
421 if (Result
.isInvalid())
423 Element
= Result
.get();
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;
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
443 S
.Diag(OrigElement
->getBeginLoc(), diag::err_box_literal_collection
)
444 << Which
<< OrigElement
->getSourceRange()
445 << FixItHint::CreateInsertion(OrigElement
->getBeginLoc(), "@");
447 Result
= S
.ObjC().BuildObjCNumericLiteral(OrigElement
->getBeginLoc(),
449 if (Result
.isInvalid())
452 Element
= Result
.get();
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(), "@");
464 S
.ObjC().BuildObjCStringLiteral(OrigElement
->getBeginLoc(), String
);
465 if (Result
.isInvalid())
468 Element
= Result
.get();
474 S
.Diag(Element
->getBeginLoc(), diag::err_invalid_collection_element
)
475 << Element
->getType();
480 if (ObjCStringLiteral
*getString
=
481 dyn_cast
<ObjCStringLiteral
>(OrigElement
)) {
482 if (StringLiteral
*SL
= getString
->getString()) {
483 unsigned numConcat
= SL
->getNumConcatenated();
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()) {
493 S
.Diag(Element
->getBeginLoc(),
494 diag::warn_concatenated_nsarray_literal
)
495 << Element
->getType();
500 // Make sure that the element has the type that the container factory
502 return S
.PerformCopyInitialization(
503 InitializedEntity::InitializeParameter(S
.Context
, T
,
505 Element
->getBeginLoc(), Element
);
508 ExprResult
SemaObjC::BuildObjCBoxedExpr(SourceRange SR
, Expr
*ValueExpr
) {
509 ASTContext
&Context
= getASTContext();
510 if (ValueExpr
->isTypeDependent()) {
511 ObjCBoxedExpr
*BoxedExpr
=
512 new (Context
) ObjCBoxedExpr(ValueExpr
, Context
.DependentTy
, nullptr, SR
);
515 ObjCMethodDecl
*BoxingMethod
= nullptr;
517 // Convert the expression to an RValue, so we can check for pointer types...
518 ExprResult RValue
= SemaRef
.DefaultFunctionArrayLvalueConversion(ValueExpr
);
519 if (RValue
.isInvalid()) {
522 SourceLocation Loc
= SR
.getBegin();
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
)) {
531 LookupObjCInterfaceDeclForLiteral(SemaRef
, Loc
, LK_String
);
535 QualType NSStringObject
= Context
.getObjCInterfaceType(NSStringDecl
);
536 NSStringPointer
= Context
.getObjCObjectPointerType(NSStringObject
);
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
)
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
)) {
552 BoxedType
= Context
.getAttributedType(NullabilityKind::NonNull
,
553 NSStringPointer
, NSStringPointer
);
554 return new (Context
) ObjCBoxedExpr(CE
, BoxedType
, nullptr, SR
);
557 Diag(SL
->getBeginLoc(), diag::warn_objc_boxing_invalid_utf8_string
)
558 << NSStringPointer
<< SL
->getSourceRange();
561 if (!StringWithUTF8StringMethod
) {
562 IdentifierInfo
*II
= &Context
.Idents
.get("stringWithUTF8String");
563 Selector stringWithUTF8String
= Context
.Selectors
.getUnarySelector(II
);
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;
570 ObjCMethodDecl
*M
= ObjCMethodDecl::Create(
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();
581 ParmVarDecl::Create(Context
, M
,
582 SourceLocation(), SourceLocation(),
583 &Context
.Idents
.get("value"),
584 Context
.getPointerType(ConstCharType
),
587 M
->setMethodParams(Context
, value
, {});
591 if (!validateBoxingMethod(SemaRef
, Loc
, NSStringDecl
,
592 stringWithUTF8String
, BoxingMethod
))
595 StringWithUTF8StringMethod
= BoxingMethod
;
598 BoxingMethod
= StringWithUTF8StringMethod
;
599 BoxedType
= NSStringPointer
;
600 // Transfer the nullability from method's return type.
601 std::optional
<NullabilityKind
> Nullability
=
602 BoxingMethod
->getReturnType()->getNullability();
605 Context
.getAttributedType(*Nullability
, BoxedType
, BoxedType
);
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>
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()) {
619 case CharacterLiteralKind::Ascii
:
620 case CharacterLiteralKind::UTF8
:
621 ValueType
= Context
.CharTy
;
624 case CharacterLiteralKind::Wide
:
625 ValueType
= Context
.getWideCharType();
628 case CharacterLiteralKind::UTF16
:
629 ValueType
= Context
.Char16Ty
;
632 case CharacterLiteralKind::UTF32
:
633 ValueType
= Context
.Char32Ty
;
637 // FIXME: Do I need to do anything special with BoolTy expressions?
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();
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 { ... };
656 // Look up the NSValue class, if we haven't done so already. It's cached
657 // in the Sema instance.
659 NSValueDecl
= LookupObjCInterfaceDeclForLiteral(SemaRef
, Loc
, LK_Boxed
);
664 // generate the pointer to NSValue type.
665 QualType NSValueObject
= Context
.getObjCInterfaceType(NSValueDecl
);
666 NSValuePointer
= Context
.getObjCObjectPointerType(NSValueObject
);
669 if (!ValueWithBytesObjCTypeMethod
) {
670 const IdentifierInfo
*II
[] = {&Context
.Idents
.get("valueWithBytes"),
671 &Context
.Idents
.get("objCType")};
672 Selector ValueWithBytesObjCType
= Context
.Selectors
.getSelector(2, II
);
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;
679 ObjCMethodDecl
*M
= ObjCMethodDecl::Create(
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);
690 SmallVector
<ParmVarDecl
*, 2> Params
;
693 ParmVarDecl::Create(Context
, M
,
694 SourceLocation(), SourceLocation(),
695 &Context
.Idents
.get("bytes"),
696 Context
.VoidPtrTy
.withConst(),
699 Params
.push_back(bytes
);
701 QualType ConstCharType
= Context
.CharTy
.withConst();
703 ParmVarDecl::Create(Context
, M
,
704 SourceLocation(), SourceLocation(),
705 &Context
.Idents
.get("type"),
706 Context
.getPointerType(ConstCharType
),
709 Params
.push_back(type
);
711 M
->setMethodParams(Context
, Params
, {});
715 if (!validateBoxingMethod(SemaRef
, Loc
, NSValueDecl
,
716 ValueWithBytesObjCType
, BoxingMethod
))
719 ValueWithBytesObjCTypeMethod
= BoxingMethod
;
722 if (!ValueType
.isTriviallyCopyableType(Context
)) {
723 Diag(Loc
, diag::err_objc_non_trivially_copyable_boxed_expression_type
)
724 << ValueType
<< ValueExpr
->getSourceRange();
728 BoxingMethod
= ValueWithBytesObjCTypeMethod
;
729 BoxedType
= NSValuePointer
;
733 Diag(Loc
, diag::err_objc_illegal_boxed_expression_type
)
734 << ValueType
<< ValueExpr
->getSourceRange();
738 SemaRef
.DiagnoseUseOfDecl(BoxingMethod
, Loc
);
740 ExprResult ConvertedValueExpr
;
741 if (ValueType
->isObjCBoxableRecordType()) {
742 InitializedEntity IE
= InitializedEntity::InitializeTemporary(ValueType
);
743 ConvertedValueExpr
= SemaRef
.PerformCopyInitialization(
744 IE
, ValueExpr
->getExprLoc(), ValueExpr
);
746 // Convert the expression to the type that the parameter requires.
747 ParmVarDecl
*ParamDecl
= BoxingMethod
->parameters()[0];
748 InitializedEntity IE
= InitializedEntity::InitializeParameter(Context
,
751 SemaRef
.PerformCopyInitialization(IE
, SourceLocation(), ValueExpr
);
754 if (ConvertedValueExpr
.isInvalid())
756 ValueExpr
= ConvertedValueExpr
.get();
758 ObjCBoxedExpr
*BoxedExpr
=
759 new (Context
) ObjCBoxedExpr(ValueExpr
, BoxedType
,
761 return SemaRef
.MaybeBindToTemporary(BoxedExpr
);
764 /// Build an ObjC subscript pseudo-object expression, given that
765 /// that's supported by the runtime.
766 ExprResult
SemaObjC::BuildObjCSubscriptExpression(
767 SourceLocation RB
, Expr
*BaseExpr
, Expr
*IndexExpr
,
768 ObjCMethodDecl
*getterMethod
, ObjCMethodDecl
*setterMethod
) {
769 assert(!getLangOpts().isSubscriptPointerArithmetic());
770 ASTContext
&Context
= getASTContext();
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");
777 // Filter out placeholders in the index. In theory, overloads could
778 // be preserved here, although that might not actually work correctly.
779 ExprResult Result
= SemaRef
.CheckPlaceholderExpr(IndexExpr
);
780 if (Result
.isInvalid())
782 IndexExpr
= Result
.get();
784 // Perform lvalue-to-rvalue conversion on the base.
785 Result
= SemaRef
.DefaultLvalueConversion(BaseExpr
);
786 if (Result
.isInvalid())
788 BaseExpr
= Result
.get();
790 // Build the pseudo-object expression.
791 return new (Context
) ObjCSubscriptRefExpr(
792 BaseExpr
, IndexExpr
, Context
.PseudoObjectTy
, VK_LValue
, OK_ObjCSubscript
,
793 getterMethod
, setterMethod
, RB
);
796 ExprResult
SemaObjC::BuildObjCArrayLiteral(SourceRange SR
,
797 MultiExprArg Elements
) {
798 ASTContext
&Context
= getASTContext();
799 SourceLocation Loc
= SR
.getBegin();
803 LookupObjCInterfaceDeclForLiteral(SemaRef
, Loc
, SemaObjC::LK_Array
);
809 // Find the arrayWithObjects:count: method, if we haven't done so already.
810 QualType IdT
= Context
.getObjCIdType();
811 if (!ArrayWithObjectsMethod
) {
813 Sel
= NSAPIObj
->getNSArraySelector(NSAPI::NSArr_arrayWithObjectsCount
);
814 ObjCMethodDecl
*Method
= NSArrayDecl
->lookupClassMethod(Sel
);
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,
823 ObjCImplementationControl::Required
, false);
824 SmallVector
<ParmVarDecl
*, 2> Params
;
825 ParmVarDecl
*objects
= ParmVarDecl::Create(Context
, Method
,
828 &Context
.Idents
.get("objects"),
829 Context
.getPointerType(IdT
),
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
,
840 Params
.push_back(cnt
);
841 Method
->setMethodParams(Context
, Params
, {});
844 if (!validateBoxingMethod(SemaRef
, Loc
, NSArrayDecl
, Sel
, Method
))
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
>();
851 !Context
.hasSameUnqualifiedType(PtrT
->getPointeeType(), IdT
)) {
852 Diag(SR
.getBegin(), diag::err_objc_literal_method_sig
)
854 Diag(Method
->parameters()[0]->getLocation(),
855 diag::note_objc_literal_method_param
)
857 << Context
.getPointerType(IdT
.withConst());
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
)
865 Diag(Method
->parameters()[1]->getLocation(),
866 diag::note_objc_literal_method_param
)
868 << Method
->parameters()[1]->getType()
873 // We've found a good +arrayWithObjects:count: method. Save it!
874 ArrayWithObjectsMethod
= Method
;
877 QualType ObjectsType
= ArrayWithObjectsMethod
->parameters()[0]->getType();
878 QualType RequiredType
= ObjectsType
->castAs
<PointerType
>()->getPointeeType();
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
) {
884 ExprResult Converted
= CheckObjCCollectionLiteralElement(
885 SemaRef
, ElementsBuffer
[I
], RequiredType
, true);
886 if (Converted
.isInvalid())
889 ElementsBuffer
[I
] = Converted
.get();
893 = Context
.getObjCObjectPointerType(
894 Context
.getObjCInterfaceType(NSArrayDecl
));
896 return SemaRef
.MaybeBindToTemporary(ObjCArrayLiteral::Create(
897 Context
, Elements
, Ty
, ArrayWithObjectsMethod
, SR
));
900 /// Check for duplicate keys in an ObjC dictionary literal. For instance:
901 /// NSDictionary *nd = @{ @"foo" : @"bar", @"foo" : @"baz" };
903 CheckObjCDictionaryLiteralDuplicateKeys(Sema
&S
,
904 ObjCDictionaryLiteral
*Literal
) {
905 if (Literal
->isValueDependent() || Literal
->isTypeDependent())
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;
917 llvm::DenseMap
<StringRef
, SourceLocation
> StringKeys
;
918 std::map
<llvm::APSInt
, SourceLocation
, APSIntCompare
> IntegralKeys
;
920 auto checkOneKey
= [&](auto &Map
, const auto &Key
, SourceLocation Loc
) {
921 auto Pair
= Map
.insert({Key
, Loc
});
923 S
.Diag(Loc
, diag::warn_nsdictionary_duplicate_key
);
924 S
.Diag(Pair
.first
->second
, diag::note_nsdictionary_duplicate_key_here
);
928 for (unsigned Idx
= 0, End
= Literal
->getNumElements(); Idx
!= End
; ++Idx
) {
929 Expr
*Key
= Literal
->getKeyValueElement(Idx
).Key
->IgnoreParenImpCasts();
931 if (auto *StrLit
= dyn_cast
<ObjCStringLiteral
>(Key
)) {
932 StringRef Bytes
= StrLit
->getString()->getBytes();
933 SourceLocation Loc
= StrLit
->getExprLoc();
934 checkOneKey(StringKeys
, Bytes
, Loc
);
937 if (auto *BE
= dyn_cast
<ObjCBoxedExpr
>(Key
)) {
938 Expr
*Boxed
= BE
->getSubExpr();
939 SourceLocation Loc
= BE
->getExprLoc();
941 // Check for @("foo").
942 if (auto *Str
= dyn_cast
<StringLiteral
>(Boxed
->IgnoreParenImpCasts())) {
943 checkOneKey(StringKeys
, Str
->getBytes(), Loc
);
947 Expr::EvalResult Result
;
948 if (Boxed
->EvaluateAsInt(Result
, S
.getASTContext(),
949 Expr::SE_AllowSideEffects
)) {
950 checkOneKey(IntegralKeys
, Result
.Val
.getInt(), Loc
);
956 ExprResult
SemaObjC::BuildObjCDictionaryLiteral(
957 SourceRange SR
, MutableArrayRef
<ObjCDictionaryElement
> Elements
) {
958 ASTContext
&Context
= getASTContext();
959 SourceLocation Loc
= SR
.getBegin();
961 if (!NSDictionaryDecl
) {
962 NSDictionaryDecl
= LookupObjCInterfaceDeclForLiteral(
963 SemaRef
, Loc
, SemaObjC::LK_Dictionary
);
964 if (!NSDictionaryDecl
) {
969 // Find the dictionaryWithObjects:forKeys:count: method, if we haven't done
971 QualType IdT
= Context
.getObjCIdType();
972 if (!DictionaryWithObjectsMethod
) {
973 Selector Sel
= NSAPIObj
->getNSDictionarySelector(
974 NSAPI::NSDict_dictionaryWithObjectsForKeysCount
);
975 ObjCMethodDecl
*Method
= NSDictionaryDecl
->lookupClassMethod(Sel
);
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,
984 ObjCImplementationControl::Required
, false);
985 SmallVector
<ParmVarDecl
*, 3> Params
;
986 ParmVarDecl
*objects
= ParmVarDecl::Create(Context
, Method
,
989 &Context
.Idents
.get("objects"),
990 Context
.getPointerType(IdT
),
991 /*TInfo=*/nullptr, SC_None
,
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
,
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
,
1009 Params
.push_back(cnt
);
1010 Method
->setMethodParams(Context
, Params
, {});
1013 if (!validateBoxingMethod(SemaRef
, SR
.getBegin(), NSDictionaryDecl
, Sel
,
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
>();
1021 !Context
.hasSameUnqualifiedType(PtrValue
->getPointeeType(), IdT
)) {
1022 Diag(SR
.getBegin(), diag::err_objc_literal_method_sig
)
1024 Diag(Method
->parameters()[0]->getLocation(),
1025 diag::note_objc_literal_method_param
)
1027 << Context
.getPointerType(IdT
.withConst());
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
>();
1035 !Context
.hasSameUnqualifiedType(PtrKey
->getPointeeType(),
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
};
1044 QIDNSCopying
= Context
.getObjCObjectType(
1045 Context
.ObjCBuiltinIdTy
, {},
1046 llvm::ArrayRef((ObjCProtocolDecl
**)PQ
, 1), false);
1047 QIDNSCopying
= Context
.getObjCObjectPointerType(QIDNSCopying
);
1050 if (!QIDNSCopying
.isNull())
1051 err
= !Context
.hasSameUnqualifiedType(PtrKey
->getPointeeType(),
1056 Diag(SR
.getBegin(), diag::err_objc_literal_method_sig
)
1058 Diag(Method
->parameters()[1]->getLocation(),
1059 diag::note_objc_literal_method_param
)
1061 << Context
.getPointerType(IdT
.withConst());
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
)
1071 Diag(Method
->parameters()[2]->getLocation(),
1072 diag::note_objc_literal_method_param
)
1078 // We've found a good +dictionaryWithObjects:keys:count: method; save it!
1079 DictionaryWithObjectsMethod
= Method
;
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();
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
) {
1093 CheckObjCCollectionLiteralElement(SemaRef
, Element
.Key
, KeyT
);
1094 if (Key
.isInvalid())
1099 CheckObjCCollectionLiteralElement(SemaRef
, Element
.Value
, ValueT
);
1100 if (Value
.isInvalid())
1103 Element
.Key
= Key
.get();
1104 Element
.Value
= Value
.get();
1106 if (Element
.EllipsisLoc
.isInvalid())
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());
1118 HasPackExpansions
= true;
1121 QualType Ty
= Context
.getObjCObjectPointerType(
1122 Context
.getObjCInterfaceType(NSDictionaryDecl
));
1125 ObjCDictionaryLiteral::Create(Context
, Elements
, HasPackExpansions
, Ty
,
1126 DictionaryWithObjectsMethod
, SR
);
1127 CheckObjCDictionaryLiteralDuplicateKeys(SemaRef
, Literal
);
1128 return SemaRef
.MaybeBindToTemporary(Literal
);
1131 ExprResult
SemaObjC::BuildObjCEncodeExpression(SourceLocation AtLoc
,
1132 TypeSourceInfo
*EncodedTypeInfo
,
1133 SourceLocation RParenLoc
) {
1134 ASTContext
&Context
= getASTContext();
1135 QualType EncodedType
= EncodedTypeInfo
->getType();
1137 if (EncodedType
->isDependentType())
1138 StrTy
= Context
.DependentTy
;
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()))
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
;
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());
1159 return new (Context
) ObjCEncodeExpr(StrTy
, EncodedTypeInfo
, AtLoc
, RParenLoc
);
1162 ExprResult
SemaObjC::ParseObjCEncodeExpression(SourceLocation AtLoc
,
1163 SourceLocation EncodeLoc
,
1164 SourceLocation LParenLoc
,
1166 SourceLocation RParenLoc
) {
1167 ASTContext
&Context
= getASTContext();
1168 // FIXME: Preserve type source info ?
1169 TypeSourceInfo
*TInfo
;
1170 QualType EncodedType
= SemaRef
.GetTypeFromParser(ty
, &TInfo
);
1172 TInfo
= Context
.getTrivialTypeSourceInfo(
1173 EncodedType
, SemaRef
.getLocForEndOfToken(LParenLoc
));
1175 return BuildObjCEncodeExpression(AtLoc
, TInfo
, RParenLoc
);
1178 static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema
&S
,
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())
1192 if (!S
.ObjC().MatchTwoMethodDeclarations(Method
, MatchingMethodDecl
,
1193 SemaObjC::MMS_loose
)) {
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();
1202 S
.Diag(MatchingMethodDecl
->getLocation(), diag::note_method_declared_at
)
1203 << MatchingMethodDecl
->getDeclName();
1209 static void DiagnoseMismatchedSelectors(Sema
&S
, SourceLocation AtLoc
,
1210 ObjCMethodDecl
*Method
,
1211 SourceLocation LParenLoc
,
1212 SourceLocation RParenLoc
,
1213 bool WarnMultipleSelectors
) {
1214 if (!WarnMultipleSelectors
||
1215 S
.Diags
.isIgnored(diag::warn_multiple_selectors
, SourceLocation()))
1217 bool Warned
= false;
1218 for (SemaObjC::GlobalMethodPool::iterator b
= S
.ObjC().MethodPool
.begin(),
1219 e
= S
.ObjC().MethodPool
.end();
1221 // first, instance methods
1222 ObjCMethodList
&InstMethList
= b
->second
.first
;
1223 if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S
, AtLoc
, LParenLoc
, RParenLoc
,
1224 Method
, InstMethList
))
1227 // second, class methods
1228 ObjCMethodList
&ClsMethList
= b
->second
.second
;
1229 if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S
, AtLoc
, LParenLoc
, RParenLoc
,
1230 Method
, ClsMethList
) || Warned
)
1235 static ObjCMethodDecl
*LookupDirectMethodInMethodList(Sema
&S
, Selector Sel
,
1236 ObjCMethodList
&MethList
,
1240 ObjCMethodList
*M
= &MethList
;
1241 ObjCMethodDecl
*DirectMethod
= nullptr;
1242 for (; M
; M
= M
->getNext()) {
1243 ObjCMethodDecl
*Method
= M
->getMethod();
1246 assert(Method
->getSelector() == Sel
&& "Method with wrong selector in method list");
1247 if (Method
->isDirectMethod()) {
1249 DirectMethod
= Method
;
1254 return DirectMethod
;
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
1261 static ObjCMethodDecl
*LookupDirectMethodInGlobalPool(Sema
&S
, Selector Sel
,
1264 auto Iter
= S
.ObjC().MethodPool
.find(Sel
);
1265 if (Iter
== S
.ObjC().MethodPool
.end())
1268 ObjCMethodDecl
*DirectInstance
= LookupDirectMethodInMethodList(
1269 S
, Sel
, Iter
->second
.first
, onlyDirect
, anyDirect
);
1270 ObjCMethodDecl
*DirectClass
= LookupDirectMethodInMethodList(
1271 S
, Sel
, Iter
->second
.second
, onlyDirect
, anyDirect
);
1273 return DirectInstance
? DirectInstance
: DirectClass
;
1276 static ObjCMethodDecl
*findMethodInCurrentClass(Sema
&S
, Selector Sel
) {
1277 auto *CurMD
= S
.getCurMethodDecl();
1280 ObjCInterfaceDecl
*IFace
= CurMD
->getClassInterface();
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))
1287 if (ObjCMethodDecl
*MD
= IFace
->lookupPrivateMethod(Sel
, /*Instance=*/true))
1289 if (ObjCMethodDecl
*MD
= IFace
->lookupMethod(Sel
, /*isInstance=*/false))
1291 if (ObjCMethodDecl
*MD
= IFace
->lookupPrivateMethod(Sel
, /*Instance=*/false))
1297 ExprResult
SemaObjC::ParseObjCSelectorExpression(Selector Sel
,
1298 SourceLocation AtLoc
,
1299 SourceLocation SelLoc
,
1300 SourceLocation LParenLoc
,
1301 SourceLocation RParenLoc
,
1302 bool WarnMultipleSelectors
) {
1303 ASTContext
&Context
= getASTContext();
1304 ObjCMethodDecl
*Method
= LookupInstanceMethodInGlobalPool(Sel
,
1305 SourceRange(LParenLoc
, RParenLoc
));
1307 Method
= LookupFactoryMethodInGlobalPool(Sel
,
1308 SourceRange(LParenLoc
, RParenLoc
));
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());
1319 Diag(SelLoc
, diag::warn_undeclared_selector
) << Sel
;
1321 DiagnoseMismatchedSelectors(SemaRef
, AtLoc
, Method
, LParenLoc
, RParenLoc
,
1322 WarnMultipleSelectors
);
1324 bool onlyDirect
= true;
1325 bool anyDirect
= false;
1326 ObjCMethodDecl
*GlobalDirectMethod
=
1327 LookupDirectMethodInGlobalPool(SemaRef
, Sel
, onlyDirect
, anyDirect
);
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
=
1339 findMethodInCurrentClass(SemaRef
, Sel
);
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
)
1350 Diag(GlobalDirectMethod
->getLocation(),
1351 diag::note_direct_method_declared_at
)
1352 << GlobalDirectMethod
->getDeclName();
1358 Method
->getImplementationControl() !=
1359 ObjCImplementationControl::Optional
&&
1360 !SemaRef
.getSourceManager().isInSystemHeader(Method
->getLocation()))
1361 ReferencedSelectors
.insert(std::make_pair(Sel
, AtLoc
));
1363 // In ARC, forbid the user from using @selector for
1364 // retain/release/autorelease/dealloc/retainCount.
1365 if (getLangOpts().ObjCAutoRefCount
) {
1366 switch (Sel
.getMethodFamily()) {
1369 case OMF_autorelease
:
1370 case OMF_retainCount
:
1372 Diag(AtLoc
, diag::err_arc_illegal_selector
) <<
1373 Sel
<< SourceRange(LParenLoc
, RParenLoc
);
1381 case OMF_mutableCopy
:
1384 case OMF_initialize
:
1385 case OMF_performSelector
:
1389 QualType Ty
= Context
.getObjCSelType();
1390 return new (Context
) ObjCSelectorExpr(Ty
, Sel
, AtLoc
, RParenLoc
);
1393 ExprResult
SemaObjC::ParseObjCProtocolExpression(IdentifierInfo
*ProtocolId
,
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
);
1402 Diag(ProtoLoc
, diag::err_undeclared_protocol
) << ProtocolId
;
1405 if (PDecl
->isNonRuntimeProtocol())
1406 Diag(ProtoLoc
, diag::err_objc_non_runtime_protocol_in_protocol_expr
)
1408 if (!PDecl
->hasDefinition()) {
1409 Diag(ProtoLoc
, diag::err_atprotocol_protocol
) << PDecl
;
1410 Diag(PDecl
->getLocation(), diag::note_entity_declared_at
) << PDecl
;
1412 PDecl
= PDecl
->getDefinition();
1415 QualType Ty
= Context
.getObjCProtoType();
1418 Ty
= Context
.getObjCObjectPointerType(Ty
);
1419 return new (Context
) ObjCProtocolExpr(Ty
, PDecl
, AtLoc
, ProtoIdLoc
, RParenLoc
);
1422 /// Try to capture an implicit reference to 'self'.
1423 ObjCMethodDecl
*SemaObjC::tryCaptureObjCSelf(SourceLocation Loc
) {
1424 DeclContext
*DC
= SemaRef
.getFunctionLevelDeclContext();
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
);
1433 SemaRef
.tryCaptureVariable(method
->getSelfDecl(), Loc
);
1438 static QualType
stripObjCInstanceType(ASTContext
&Context
, QualType T
) {
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());
1449 if (T
== Context
.getObjCInstanceType())
1450 return Context
.getObjCIdType();
1455 /// Determine the result type of a message send based on the receiver type,
1456 /// method, and the kind of message send.
1458 /// This is the "base" result type, which will still need to be adjusted
1459 /// to account for nullability.
1460 static QualType
getBaseMessageSendResultType(Sema
&S
,
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
);
1469 ASTContext
&Context
= S
.Context
;
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.
1478 (void)AttributedType::stripOuterNullability(type
);
1480 // Form a new attributed type using the method result type's nullability.
1481 return Context
.getAttributedType(*nullability
, type
, type
);
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
1491 if (Method
->isInstanceMethod() && isClassMessage
)
1492 return stripObjCInstanceType(Context
,
1493 Method
->getSendResultType(ReceiverType
));
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(
1501 Context
.getObjCObjectPointerType(
1502 Context
.getObjCInterfaceType(Class
)));
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
));
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
);
1522 QualType
SemaObjC::getMessageSendResultType(const Expr
*Receiver
,
1523 QualType ReceiverType
,
1524 ObjCMethodDecl
*Method
,
1525 bool isClassMessage
,
1526 bool isSuperMessage
) {
1527 ASTContext
&Context
= getASTContext();
1528 // Produce the result type.
1529 QualType resultType
= getBaseMessageSendResultType(
1530 SemaRef
, ReceiverType
, Method
, isClassMessage
, isSuperMessage
);
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
);
1542 AttributedType::stripOuterNullability(T
);
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(
1550 Context
.getObjCInterfaceType(MD
->getClassInterface()));
1551 if (auto Nullability
= resultType
->getNullability())
1552 NewResultType
= Context
.getAttributedType(*Nullability
, NewResultType
,
1554 return NewResultType
;
1560 // There is nothing left to do if the result type cannot have a nullability
1562 if (!resultType
->canHaveNullability())
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
);
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
);
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
}
1596 unsigned newResultNullabilityIdx
1597 = nullabilityMap
[receiverNullabilityIdx
][resultNullabilityIdx
];
1598 if (newResultNullabilityIdx
== resultNullabilityIdx
)
1601 // Strip off the existing nullability. This removes as little type sugar as
1604 if (auto attributed
= dyn_cast
<AttributedType
>(resultType
.getTypePtr())) {
1605 resultType
= attributed
->getModifiedType();
1607 resultType
= resultType
.getDesugaredType(Context
);
1609 } while (resultType
->getNullability());
1611 // Add nullability back if needed.
1612 if (newResultNullabilityIdx
> 0) {
1614 = static_cast<NullabilityKind
>(newResultNullabilityIdx
-1);
1615 return Context
.getAttributedType(newNullability
, resultType
, resultType
);
1621 /// Look for an ObjC method whose result type exactly matches the given type.
1622 static const ObjCMethodDecl
*
1623 findExplicitInstancetypeDeclarer(const ObjCMethodDecl
*MD
,
1624 QualType instancetype
) {
1625 if (MD
->getReturnType() == instancetype
)
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();
1637 iface
= impl
->getClassInterface();
1640 const ObjCMethodDecl
*ifaceMD
=
1641 iface
->getMethod(MD
->getSelector(), MD
->isInstanceMethod());
1642 if (ifaceMD
) return findExplicitInstancetypeDeclarer(ifaceMD
, instancetype
);
1645 SmallVector
<const ObjCMethodDecl
*, 4> overrides
;
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
))
1656 void SemaObjC::EmitRelatedResultTypeNoteForReturn(QualType destType
) {
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()))
1665 // Look for a method overridden by this method which explicitly uses
1667 if (const ObjCMethodDecl
*overridden
=
1668 findExplicitInstancetypeDeclarer(MD
, Context
.getObjCInstanceType())) {
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
;
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
1686 void SemaObjC::EmitRelatedResultTypeNote(const Expr
*E
) {
1687 ASTContext
&Context
= getASTContext();
1688 E
= E
->IgnoreParenImpCasts();
1689 const ObjCMessageExpr
*MsgSend
= dyn_cast
<ObjCMessageExpr
>(E
);
1693 const ObjCMethodDecl
*Method
= MsgSend
->getMethodDecl();
1697 if (!Method
->hasRelatedResultType())
1700 if (Context
.hasSameUnqualifiedType(
1701 Method
->getReturnType().getNonReferenceType(), MsgSend
->getType()))
1704 if (!Context
.hasSameUnqualifiedType(Method
->getReturnType(),
1705 Context
.getObjCInstanceType()))
1708 Diag(Method
->getLocation(), diag::note_related_result_type_inferred
)
1709 << Method
->isInstanceMethod() << Method
->getSelector()
1710 << MsgSend
->getType();
1713 bool SemaObjC::CheckMessageArgumentTypes(
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();
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())
1733 if (getLangOpts().DebuggerSupport
) {
1734 QualType paramTy
; // ignored
1735 result
= SemaRef
.checkUnknownAnyArg(SelLoc
, Args
[i
], paramTy
);
1737 result
= SemaRef
.DefaultArgumentPromotion(Args
[i
]);
1739 if (result
.isInvalid())
1741 Args
[i
] = result
.get();
1745 if (getLangOpts().ObjCAutoRefCount
)
1746 DiagID
= diag::err_arc_method_not_found
;
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
;
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());
1765 Diag(SelLoc
, DiagID
) << Sel
<< isClassMessage
<< MatchedSel
;
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());
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
;
1789 ReturnType
= Context
.getObjCIdType();
1795 ReturnType
= getMessageSendResultType(Receiver
, ReceiverType
, Method
,
1796 isClassMessage
, isSuperMessage
);
1797 VK
= Expr::getValueKindForType(Method
->getReturnType());
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;
1812 // Compute the set of type arguments to be substituted into each parameter
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())
1822 Expr
*argExpr
= Args
[i
];
1824 ParmVarDecl
*param
= Method
->parameters()[i
];
1825 assert(argExpr
&& "CheckMessageArgumentTypes(): missing expression");
1827 if (param
->hasAttr
<NoEscapeAttr
>() &&
1828 param
->getType()->isBlockPointerType())
1829 if (auto *BE
= dyn_cast
<BlockExpr
>(
1830 argExpr
->IgnoreParenNoopCasts(Context
)))
1831 BE
->getBlockDecl()->setDoesNotEscape();
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
);
1839 // If the parameter is __unknown_anytype, infer its type
1840 // from the argument.
1841 if (param
->getType() == Context
.UnknownAnyTy
) {
1843 ExprResult argE
= SemaRef
.checkUnknownAnyArg(SelLoc
, argExpr
, paramType
);
1844 if (argE
.isInvalid()) {
1847 Args
[i
] = argE
.get();
1849 // Update the parameter type in-place.
1850 param
->setType(paramType
);
1855 QualType origParamType
= param
->getType();
1856 QualType paramType
= param
->getType();
1858 paramType
= paramType
.substObjCTypeArgs(
1861 ObjCSubstitutionContext::Parameter
);
1863 if (SemaRef
.RequireCompleteType(
1864 argExpr
->getSourceRange().getBegin(), paramType
,
1865 diag::err_call_incomplete_argument
, argExpr
))
1868 InitializedEntity Entity
1869 = InitializedEntity::InitializeParameter(Context
, param
, paramType
);
1871 SemaRef
.PerformCopyInitialization(Entity
, SourceLocation(), argExpr
);
1872 if (ArgE
.isInvalid())
1875 Args
[i
] = ArgE
.getAs
<Expr
>();
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
];
1884 SemaRef
.maybeExtendBlockObject(arg
);
1885 Args
[i
] = arg
.get();
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())
1896 ExprResult Arg
= SemaRef
.DefaultVariadicArgumentPromotion(
1897 Args
[i
], Sema::VariadicMethod
, nullptr);
1898 IsError
|= Arg
.isInvalid();
1899 Args
[i
] = Arg
.get();
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());
1913 SemaRef
.DiagnoseSentinelCalls(Method
, SelLoc
, Args
);
1915 // Do additional checkings on method.
1917 CheckObjCMethodCall(Method
, SelLoc
, ArrayRef(Args
.data(), Args
.size()));
1922 bool SemaObjC::isSelfExpr(Expr
*RExpr
) {
1923 // 'self' is objc 'self' in an objc method only.
1924 ObjCMethodDecl
*Method
= dyn_cast_or_null
<ObjCMethodDecl
>(
1925 SemaRef
.CurContext
->getNonClosureAncestor());
1926 return isSelfExpr(RExpr
, Method
);
1929 bool SemaObjC::isSelfExpr(Expr
*receiver
, const ObjCMethodDecl
*method
) {
1930 if (!method
) return false;
1932 receiver
= receiver
->IgnoreParenLValueCasts();
1933 if (DeclRefExpr
*DRE
= dyn_cast
<DeclRefExpr
>(receiver
))
1934 if (DRE
->getDecl() == method
->getSelfDecl())
1939 /// LookupMethodInType - Look up a method in an ObjCObjectType.
1940 ObjCMethodDecl
*SemaObjC::LookupMethodInObjectType(Selector sel
, QualType type
,
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
))
1948 // Okay, look for "private" methods declared in any
1949 // @implementations we've seen.
1950 if (ObjCMethodDecl
*method
= iface
->lookupPrivateMethod(sel
, isInstance
))
1954 // Check qualifiers.
1955 for (const auto *I
: objType
->quals())
1956 if (ObjCMethodDecl
*method
= I
->lookupMethod(sel
, isInstance
))
1962 /// LookupMethodInQualifiedType - Lookups up a method in protocol qualifier
1963 /// list of a qualified objective pointer type.
1964 ObjCMethodDecl
*SemaObjC::LookupMethodInQualifiedType(
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
))) {
1975 /// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an
1976 /// objective C interface. This is a property reference expression.
1977 ExprResult
SemaObjC::HandleExprPropertyRefExpr(
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();
1985 if (!MemberName
.isIdentifier()) {
1986 Diag(MemberLoc
, diag::err_invalid_property_name
)
1987 << MemberName
<< QualType(OPT
, 0);
1991 IdentifierInfo
*Member
= MemberName
.getAsIdentifierInfo();
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
))
2000 if (ObjCPropertyDecl
*PD
= IFace
->FindPropertyDeclaration(
2001 Member
, ObjCPropertyQueryKind::OBJC_PR_query_instance
)) {
2002 // Check whether we can reference this property.
2003 if (SemaRef
.DiagnoseUseOfDecl(PD
, MemberLoc
))
2006 return new (Context
)
2007 ObjCPropertyRefExpr(PD
, Context
.PseudoObjectTy
, VK_LValue
,
2008 OK_ObjCProperty
, MemberLoc
, SuperLoc
, SuperType
);
2010 return new (Context
)
2011 ObjCPropertyRefExpr(PD
, Context
.PseudoObjectTy
, VK_LValue
,
2012 OK_ObjCProperty
, MemberLoc
, BaseExpr
);
2014 // Check protocols on qualified interfaces.
2015 for (const auto *I
: OPT
->quals())
2016 if (ObjCPropertyDecl
*PD
= I
->FindPropertyDeclaration(
2017 Member
, ObjCPropertyQueryKind::OBJC_PR_query_instance
)) {
2018 // Check whether we can reference this property.
2019 if (SemaRef
.DiagnoseUseOfDecl(PD
, MemberLoc
))
2023 return new (Context
) ObjCPropertyRefExpr(
2024 PD
, Context
.PseudoObjectTy
, VK_LValue
, OK_ObjCProperty
, MemberLoc
,
2025 SuperLoc
, SuperType
);
2027 return new (Context
)
2028 ObjCPropertyRefExpr(PD
, Context
.PseudoObjectTy
, VK_LValue
,
2029 OK_ObjCProperty
, MemberLoc
, BaseExpr
);
2031 // If that failed, look for an "implicit" property by seeing if the nullary
2032 // selector is implemented.
2034 // FIXME: The logic for looking up nullary and unary selectors should be
2035 // shared with the code in ActOnInstanceMessage.
2037 Selector Sel
= SemaRef
.PP
.getSelectorTable().getNullarySelector(Member
);
2038 ObjCMethodDecl
*Getter
= IFace
->lookupInstanceMethod(Sel
);
2040 // May be found in property's qualified list.
2042 Getter
= LookupMethodInQualifiedType(Sel
, OPT
, true);
2044 // If this reference is in an @implementation, check for 'private' methods.
2046 Getter
= IFace
->lookupPrivateMethod(Sel
);
2049 // Check if we can reference this property.
2050 if (SemaRef
.DiagnoseUseOfDecl(Getter
, MemberLoc
))
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.
2055 Selector SetterSel
= SelectorTable::constructSetterSelector(
2056 SemaRef
.PP
.getIdentifierTable(), SemaRef
.PP
.getSelectorTable(), Member
);
2057 ObjCMethodDecl
*Setter
= IFace
->lookupInstanceMethod(SetterSel
);
2059 // May be found in property's qualified list.
2061 Setter
= LookupMethodInQualifiedType(SetterSel
, OPT
, true);
2064 // If this reference is in an @implementation, also check for 'private'
2066 Setter
= IFace
->lookupPrivateMethod(SetterSel
);
2069 if (Setter
&& SemaRef
.DiagnoseUseOfDecl(Setter
, MemberLoc
))
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
2075 if (Setter
&& Setter
->isImplicit() && Setter
->isPropertyAccessor() &&
2076 !IFace
->FindPropertyDeclaration(
2077 Member
, ObjCPropertyQueryKind::OBJC_PR_query_instance
)) {
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() &
2082 ObjCPropertyAttribute::kind_setter
))
2084 diag::warn_property_access_suggest
)
2085 << MemberName
<< QualType(OPT
, 0) << PDecl
->getName()
2086 << FixItHint::CreateReplacement(MemberLoc
, PDecl
->getName());
2090 if (Getter
|| Setter
) {
2092 return new (Context
)
2093 ObjCPropertyRefExpr(Getter
, Setter
, Context
.PseudoObjectTy
, VK_LValue
,
2094 OK_ObjCProperty
, MemberLoc
, SuperLoc
, SuperType
);
2096 return new (Context
)
2097 ObjCPropertyRefExpr(Getter
, Setter
, Context
.PseudoObjectTy
, VK_LValue
,
2098 OK_ObjCProperty
, MemberLoc
, BaseExpr
);
2102 // Attempt to correct for typos in property names.
2103 DeclFilterCCC
<ObjCPropertyDecl
> CCC
{};
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
2117 Diag(MemberLoc
, diag::err_class_property_found
) << MemberName
2118 << OPT
->getInterfaceDecl()->getName()
2119 << FixItHint::CreateReplacement(BaseExpr
->getSourceRange(),
2120 OPT
->getInterfaceDecl()->getName());
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
);
2132 ObjCInterfaceDecl
*ClassDeclared
;
2133 if (ObjCIvarDecl
*Ivar
=
2134 IFace
->lookupInstanceVariable(Member
, ClassDeclared
)) {
2135 QualType T
= Ivar
->getType();
2136 if (const ObjCObjectPointerType
* OBJPT
=
2137 T
->getAsObjCInterfacePointerType()) {
2138 if (SemaRef
.RequireCompleteType(MemberLoc
, OBJPT
->getPointeeType(),
2139 diag::err_property_not_as_forward_class
,
2140 MemberName
, BaseExpr
))
2144 diag::err_ivar_access_using_property_syntax_suggest
)
2145 << MemberName
<< QualType(OPT
, 0) << Ivar
->getDeclName()
2146 << FixItHint::CreateReplacement(OpLoc
, "->");
2150 Diag(MemberLoc
, diag::err_property_not_found
)
2151 << MemberName
<< QualType(OPT
, 0);
2153 Diag(Setter
->getLocation(), diag::note_getter_unavailable
)
2154 << MemberName
<< BaseExpr
->getSourceRange();
2158 ExprResult
SemaObjC::ActOnClassPropertyRefExpr(
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
,
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();
2181 QualType T
= Context
.getObjCObjectPointerType(SuperType
);
2183 return HandleExprPropertyRefExpr(T
->castAs
<ObjCObjectPointerType
>(),
2184 /*BaseExpr*/nullptr,
2185 SourceLocation()/*OpLoc*/,
2188 receiverNameLoc
, T
, true);
2191 // Otherwise, if this is a class method, try dispatching to our
2193 IFace
= CurMethod
->getClassInterface()->getSuperClass();
2199 Diag(receiverNameLoc
, diag::err_expected_either
) << tok::identifier
2207 if (auto PD
= IFace
->FindPropertyDeclaration(
2208 &propertyName
, ObjCPropertyQueryKind::OBJC_PR_query_class
)) {
2209 GetterSel
= PD
->getGetterName();
2210 SetterSel
= PD
->getSetterName();
2212 GetterSel
= SemaRef
.PP
.getSelectorTable().getNullarySelector(&propertyName
);
2213 SetterSel
= SelectorTable::constructSetterSelector(
2214 SemaRef
.PP
.getIdentifierTable(), SemaRef
.PP
.getSelectorTable(),
2218 // Search for a declared property first.
2219 ObjCMethodDecl
*Getter
= IFace
->lookupClassMethod(GetterSel
);
2221 // If this reference is in an @implementation, check for 'private' methods.
2223 Getter
= IFace
->lookupPrivateClassMethod(GetterSel
);
2226 // FIXME: refactor/share with ActOnMemberReference().
2227 // Check if we can reference this property.
2228 if (SemaRef
.DiagnoseUseOfDecl(Getter
, propertyNameLoc
))
2232 // Look for the matching setter, in case it is needed.
2233 ObjCMethodDecl
*Setter
= IFace
->lookupClassMethod(SetterSel
);
2235 // If this reference is in an @implementation, also check for 'private'
2237 Setter
= IFace
->lookupPrivateClassMethod(SetterSel
);
2239 // Look through local category implementations associated with the class.
2241 Setter
= IFace
->getCategoryClassMethod(SetterSel
);
2243 if (Setter
&& SemaRef
.DiagnoseUseOfDecl(Setter
, propertyNameLoc
))
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
,
2253 return new (Context
) ObjCPropertyRefExpr(
2254 Getter
, Setter
, Context
.PseudoObjectTy
, VK_LValue
, OK_ObjCProperty
,
2255 propertyNameLoc
, receiverNameLoc
, IFace
);
2257 return ExprError(Diag(propertyNameLoc
, diag::err_property_not_found
)
2258 << &propertyName
<< Context
.getObjCInterfaceType(IFace
));
2263 class ObjCInterfaceOrSuperCCC final
: public CorrectionCandidateCallback
{
2265 ObjCInterfaceOrSuperCCC(ObjCMethodDecl
*Method
) {
2266 // Determine whether "super" is acceptable in the current context.
2267 if (Method
&& Method
->getClassInterface())
2268 WantObjCSuper
= Method
->getClassInterface()->getSuperClass();
2271 bool ValidateCandidate(const TypoCorrection
&candidate
) override
{
2272 return candidate
.getCorrectionDeclAs
<ObjCInterfaceDecl
>() ||
2273 candidate
.isKeyword("super");
2276 std::unique_ptr
<CorrectionCandidateCallback
> clone() override
{
2277 return std::make_unique
<ObjCInterfaceOrSuperCCC
>(*this);
2281 } // end anonymous namespace
2283 SemaObjC::ObjCMessageKind
2284 SemaObjC::getObjCMessageKind(Scope
*S
, IdentifierInfo
*Name
,
2285 SourceLocation NameLoc
, bool IsSuper
,
2286 bool HasTrailingDot
, ParsedType
&ReceiverType
) {
2287 ASTContext
&Context
= getASTContext();
2288 ReceiverType
= nullptr;
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
;
2296 LookupResult
Result(SemaRef
, Name
, NameLoc
, Sema::LookupOrdinaryName
);
2297 SemaRef
.LookupName(Result
, S
);
2299 switch (Result
.getResultKind()) {
2300 case LookupResult::NotFound
:
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
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
;
2311 ObjCInterfaceDecl
*ClassDeclared
;
2312 if (Method
->getClassInterface()->lookupInstanceVariable(Name
,
2314 return ObjCInstanceMessage
;
2317 // Break out; we'll perform typo correction below.
2320 case LookupResult::NotFoundInCurrentInstantiation
:
2321 case LookupResult::FoundOverloaded
:
2322 case LookupResult::FoundUnresolvedValue
:
2323 case LookupResult::Ambiguous
:
2324 Result
.suppressDiagnostics();
2325 return ObjCInstanceMessage
;
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.
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();
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
);
2343 return ObjCInstanceMessage
;
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
;
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
)
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
2367 SemaRef
.diagnoseTypo(Corrected
, PDiag(diag::err_unknown_receiver_suggest
)
2369 QualType T
= Context
.getObjCInterfaceType(Class
);
2370 TypeSourceInfo
*TSInfo
= Context
.getTrivialTypeSourceInfo(T
, NameLoc
);
2371 ReceiverType
= SemaRef
.CreateParsedType(T
, TSInfo
);
2372 return ObjCClassMessage
;
2376 // Fall back: let the parser try to parse it as an instance message.
2377 return ObjCInstanceMessage
;
2380 ExprResult
SemaObjC::ActOnSuperMessage(Scope
*S
, SourceLocation SuperLoc
,
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
);
2389 Diag(SuperLoc
, diag::err_invalid_receiver_to_message_super
);
2393 ObjCInterfaceDecl
*Class
= Method
->getClassInterface();
2395 Diag(SuperLoc
, diag::err_no_super_class_message
)
2396 << Method
->getDeclName();
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();
2408 // We are in a method whose class has a superclass, so 'super'
2409 // is acting as a keyword.
2410 if (Method
->getSelector() == Sel
)
2411 SemaRef
.getCurFunction()->ObjCShouldCallSuper
= false;
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
);
2422 // Since we are in a class method, this is a class message to
2424 return BuildClassMessage(/*ReceiverTypeInfo=*/nullptr,
2426 SuperLoc
, Sel
, /*Method=*/nullptr,
2427 LBracLoc
, SelectorLocs
, RBracLoc
, Args
);
2430 ExprResult
SemaObjC::BuildClassMessageImplicit(QualType ReceiverType
,
2431 bool isSuperReceiver
,
2432 SourceLocation Loc
, Selector Sel
,
2433 ObjCMethodDecl
*Method
,
2434 MultiExprArg Args
) {
2435 ASTContext
&Context
= getASTContext();
2436 TypeSourceInfo
*receiverTypeInfo
= nullptr;
2437 if (!ReceiverType
.isNull())
2438 receiverTypeInfo
= Context
.getTrivialTypeSourceInfo(ReceiverType
);
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);
2449 static void applyCocoaAPICheck(Sema
&S
, const ObjCMessageExpr
*Msg
,
2451 bool (*refactor
)(const ObjCMessageExpr
*,
2452 const NSAPI
&, edit::Commit
&)) {
2453 SourceLocation MsgLoc
= Msg
->getExprLoc();
2454 if (S
.Diags
.isIgnored(DiagID
, MsgLoc
))
2457 SourceManager
&SM
= S
.SourceMgr
;
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())
2465 for (edit::Commit::edit_iterator
2466 I
= ECommit
.edit_begin(), E
= ECommit
.edit_end(); I
!= E
; ++I
) {
2467 const edit::Commit::Edit
&Edit
= *I
;
2468 switch (Edit
.Kind
) {
2469 case edit::Commit::Act_Insert
:
2470 Builder
.AddFixItHint(FixItHint::CreateInsertion(Edit
.OrigLoc
,
2474 case edit::Commit::Act_InsertFromRange
:
2475 Builder
.AddFixItHint(
2476 FixItHint::CreateInsertionFromRange(Edit
.OrigLoc
,
2477 Edit
.getInsertFromRange(SM
),
2480 case edit::Commit::Act_Remove
:
2481 Builder
.AddFixItHint(FixItHint::CreateRemoval(Edit
.getFileRange(SM
)));
2488 static void checkCocoaAPI(Sema
&S
, const ObjCMessageExpr
*Msg
) {
2489 applyCocoaAPICheck(S
, Msg
, diag::warn_objc_redundant_literal_use
,
2490 edit::rewriteObjCRedundantCallWithLiteral
);
2493 static void checkFoundationAPI(Sema
&S
, SourceLocation Loc
,
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
||
2502 const auto *SE
= dyn_cast
<ObjCSelectorExpr
>(Args
[0]->IgnoreParens());
2505 ObjCMethodDecl
*ImpliedMethod
;
2506 if (!IsClassObjectCall
) {
2507 const auto *OPT
= ReceiverType
->getAs
<ObjCObjectPointerType
>();
2508 if (!OPT
|| !OPT
->getInterfaceDecl())
2511 OPT
->getInterfaceDecl()->lookupInstanceMethod(SE
->getSelector());
2514 OPT
->getInterfaceDecl()->lookupPrivateMethod(SE
->getSelector());
2516 const auto *IT
= ReceiverType
->getAs
<ObjCInterfaceType
>();
2519 ImpliedMethod
= IT
->getDecl()->lookupClassMethod(SE
->getSelector());
2522 IT
->getDecl()->lookupPrivateClassMethod(SE
->getSelector());
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()
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
;
2539 /// Diagnose use of %s directive in an NSString which is being passed
2540 /// as formatting string to formatting method.
2542 DiagnoseCStringFormatDirectiveInObjCAPI(Sema
&S
,
2543 ObjCMethodDecl
*Method
,
2545 Expr
**Args
, unsigned NumArgs
) {
2547 bool Format
= false;
2548 ObjCStringFormatFamily SFFamily
= Sel
.getStringFormatFamily();
2549 if (SFFamily
== ObjCStringFormatFamily::SFF_NSString
) {
2554 for (const auto *I
: Method
->specific_attrs
<FormatAttr
>()) {
2555 if (S
.ObjC().GetFormatNSStringIdx(I
, Idx
)) {
2561 if (!Format
|| NumArgs
<= Idx
)
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
)
2572 S
.Diag(Method
->getLocation(), diag::note_method_declared_at
)
2573 << Method
->getDeclName();
2578 /// Build an Objective-C class message expression.
2580 /// This routine takes care of both normal class messages and
2581 /// class messages to the superclass.
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
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
2593 /// \param SuperLoc The location of the "super" keyword in a
2594 /// superclass message.
2596 /// \param Sel The selector to which the message is being sent.
2598 /// \param Method The method that this class message is invoking, if
2601 /// \param LBracLoc The location of the opening square bracket ']'.
2603 /// \param RBracLoc The location of the closing square bracket ']'.
2605 /// \param ArgsIn The message arguments.
2606 ExprResult
SemaObjC::BuildClassMessage(
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
)
2616 << FixItHint::CreateInsertion(Loc
, "[");
2619 ArrayRef
<SourceLocation
> SelectorSlotLocs
;
2620 if (!SelectorLocs
.empty() && SelectorLocs
.front().isValid())
2621 SelectorSlotLocs
= SelectorLocs
;
2623 SelectorSlotLocs
= Loc
;
2624 SourceLocation SelLoc
= SelectorSlotLocs
.front();
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
);
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
)
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.
2652 SourceRange TypeRange
2653 = SuperLoc
.isValid()? SourceRange(SuperLoc
)
2654 : ReceiverTypeInfo
->getTypeLoc().getSourceRange();
2655 if (SemaRef
.RequireCompleteType(Loc
, Context
.getObjCInterfaceType(Class
),
2656 (getLangOpts().ObjCAutoRefCount
2657 ? diag::err_arc_receiver_forward_class
2658 : diag::warn_receiver_forward_class
),
2660 // A forward class used in messaging is treated as a 'Class'
2661 Method
= LookupFactoryMethodInGlobalPool(Sel
,
2662 SourceRange(LBracLoc
, RBracLoc
));
2663 if (Method
&& !getLangOpts().ObjCAutoRefCount
)
2664 Diag(Method
->getLocation(), diag::note_method_sent_forward_class
)
2665 << Method
->getDeclName();
2668 Method
= Class
->lookupClassMethod(Sel
);
2670 // If we have an implementation in scope, check "private" methods.
2672 Method
= Class
->lookupPrivateClassMethod(Sel
);
2674 if (Method
&& SemaRef
.DiagnoseUseOfDecl(Method
, SelectorSlotLocs
, nullptr,
2675 false, false, Class
))
2679 // Check the argument types and determine the result type.
2680 QualType ReturnType
;
2681 ExprValueKind VK
= VK_PRValue
;
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
))
2691 if (Method
&& !Method
->getReturnType()->isVoidType() &&
2692 SemaRef
.RequireCompleteType(
2693 LBracLoc
, Method
->getReturnType(),
2694 diag::err_illegal_message_expr_incomplete_type
))
2697 if (Method
&& Method
->isDirectMethod() && SuperLoc
.isValid()) {
2698 Diag(SuperLoc
, diag::err_messaging_super_with_direct_method
)
2699 << FixItHint::CreateReplacement(
2700 SuperLoc
, getLangOpts().ObjCAutoRefCount
2702 : Method
->getClassInterface()->getName());
2703 Diag(Method
->getLocation(), diag::note_direct_method_declared_at
)
2704 << Method
->getDeclName();
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());
2713 Diag(Loc
, diag::warn_direct_initialize_call
);
2714 Diag(Method
->getLocation(), diag::note_method_declared_at
)
2715 << Method
->getDeclName();
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();
2729 DiagnoseCStringFormatDirectiveInObjCAPI(SemaRef
, Method
, Sel
, Args
, NumArgs
);
2731 // Construct the appropriate ObjCMessageExpr.
2732 ObjCMessageExpr
*Result
;
2733 if (SuperLoc
.isValid())
2734 Result
= ObjCMessageExpr::Create(
2735 Context
, ReturnType
, VK
, LBracLoc
, SuperLoc
, /*IsInstanceSuper=*/false,
2736 ReceiverType
, Sel
, SelectorLocs
, Method
, ArrayRef(Args
, NumArgs
),
2737 RBracLoc
, isImplicit
);
2739 Result
= ObjCMessageExpr::Create(
2740 Context
, ReturnType
, VK
, LBracLoc
, ReceiverTypeInfo
, Sel
, SelectorLocs
,
2741 Method
, ArrayRef(Args
, NumArgs
), RBracLoc
, isImplicit
);
2743 checkCocoaAPI(SemaRef
, Result
);
2746 checkFoundationAPI(SemaRef
, SelLoc
, Method
, ArrayRef(Args
, NumArgs
),
2747 ReceiverType
, /*IsClassObjectCall=*/true);
2748 return SemaRef
.MaybeBindToTemporary(Result
);
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().
2754 ExprResult
SemaObjC::ActOnClassMessage(Scope
*S
, ParsedType Receiver
,
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())
2766 if (!ReceiverTypeInfo
)
2767 ReceiverTypeInfo
= Context
.getTrivialTypeSourceInfo(ReceiverType
, LBracLoc
);
2769 return BuildClassMessage(ReceiverTypeInfo
, ReceiverType
,
2770 /*SuperLoc=*/SourceLocation(), Sel
,
2771 /*Method=*/nullptr, LBracLoc
, SelectorLocs
, RBracLoc
,
2775 ExprResult
SemaObjC::BuildInstanceMessageImplicit(
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);
2784 static bool isMethodDeclaredInRootProtocol(Sema
&S
, const ObjCMethodDecl
*M
) {
2785 if (!S
.ObjC().NSAPIObj
)
2787 const auto *Protocol
= dyn_cast
<ObjCProtocolDecl
>(M
->getDeclContext());
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(),
2794 Sema::LookupOrdinaryName
))) {
2795 for (const ObjCProtocolDecl
*P
: RootClass
->all_referenced_protocols()) {
2796 if (P
->getCanonicalDecl() == Protocol
->getCanonicalDecl())
2803 /// Build an Objective-C instance message expression.
2805 /// This routine takes care of both normal instance messages and
2806 /// instance messages to the superclass instance.
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.
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.
2818 /// \param SuperLoc The location of the "super" keyword in a
2819 /// superclass instance message.
2821 /// \param Sel The selector to which the message is being sent.
2823 /// \param Method The method that this instance message is invoking, if
2826 /// \param LBracLoc The location of the opening square bracket ']'.
2828 /// \param RBracLoc The location of the closing square bracket ']'.
2830 /// \param ArgsIn The message arguments.
2831 ExprResult
SemaObjC::BuildInstanceMessage(
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 "
2839 ASTContext
&Context
= getASTContext();
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
;
2849 SelectorSlotLocs
= Loc
;
2850 SourceLocation SelLoc
= SelectorSlotLocs
.front();
2852 if (LBracLoc
.isInvalid()) {
2853 Diag(Loc
, diag::err_missing_open_square_message_send
)
2854 << FixItHint::CreateInsertion(Loc
, "[");
2858 // If we have a receiver expression, perform appropriate promotions
2859 // and determine receiver type.
2861 if (Receiver
->hasPlaceholderType()) {
2863 if (Receiver
->getType() == Context
.UnknownAnyTy
)
2865 SemaRef
.forceUnknownAnyToType(Receiver
, Context
.getObjCIdType());
2867 Result
= SemaRef
.CheckPlaceholderExpr(Receiver
);
2868 if (Result
.isInvalid()) return ExprError();
2869 Receiver
= Result
.get();
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");
2878 return ObjCMessageExpr::Create(
2879 Context
, Context
.DependentTy
, VK_PRValue
, LBracLoc
, Receiver
, Sel
,
2880 SelectorLocs
, /*Method=*/nullptr, ArrayRef(Args
, NumArgs
), RBracLoc
,
2884 // If necessary, apply function/array conversion to the receiver.
2885 // C99 6.7.5.3p[7,8].
2886 ExprResult Result
= SemaRef
.DefaultFunctionArrayLvalueConversion(Receiver
);
2887 if (Result
.isInvalid())
2889 Receiver
= Result
.get();
2890 ReceiverType
= Receiver
->getType();
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()) {
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.
2903 Diag(Loc
, diag::warn_bad_receiver_type
) << ReceiverType
<< RecRange
;
2904 if (ReceiverType
->isPointerType()) {
2906 .ImpCastExprToType(Receiver
, Context
.getObjCIdType(),
2907 CK_CPointerToObjCPointerCast
)
2910 // TODO: specialized warning on null receivers?
2911 bool IsNull
= Receiver
->isNullPointerConstant(Context
,
2912 Expr::NPC_ValueDependentIsNull
);
2913 CastKind Kind
= IsNull
? CK_NullToPointer
: CK_IntegralToPointer
;
2915 SemaRef
.ImpCastExprToType(Receiver
, Context
.getObjCIdType(), Kind
)
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
))
2926 SemaRef
.PerformContextuallyConvertToObjCPointer(Receiver
);
2927 if (result
.isUsable()) {
2928 Receiver
= result
.get();
2929 ReceiverType
= Receiver
->getType();
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.
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
,
2944 if (receiverIsIdLike
|| ReceiverType
->isBlockPointerType() ||
2945 (Receiver
&& Context
.isObjCNSObjectType(Receiver
->getType()))) {
2946 SmallVector
<ObjCMethodDecl
*, 4> Methods
;
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];
2955 if (ObjCMethodDecl
*BestMethod
= SemaRef
.SelectBestMethod(
2956 Sel
, ArgsIn
, Method
->isInstanceMethod(), Methods
))
2957 Method
= BestMethod
;
2959 if (!AreMultipleMethodsInGlobalPool(Sel
, Method
,
2960 SourceRange(LBracLoc
, RBracLoc
),
2961 receiverIsIdLike
, Methods
))
2962 SemaRef
.DiagnoseUseOfDecl(Method
, SelectorSlotLocs
);
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,
2970 if (!ReceiverType
->isObjCClassOrClassKindOfType()) {
2971 const ObjCObjectPointerType
*QClassTy
2972 = ReceiverType
->getAsObjCQualifiedClassType();
2973 // Search protocols for class methods.
2974 Method
= LookupMethodInQualifiedType(Sel
, QClassTy
, false);
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();
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.
2991 // First check the public methods in the class interface.
2992 Method
= ClassDecl
->lookupClassMethod(Sel
);
2995 Method
= ClassDecl
->lookupPrivateClassMethod(Sel
);
2997 if (Method
&& SemaRef
.DiagnoseUseOfDecl(Method
, SelectorSlotLocs
))
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.
3006 SmallVector
<ObjCMethodDecl
*, 4> Methods
;
3007 CollectMultipleMethodsInGlobalPool(Sel
, Methods
,
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];
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
);
3025 if (ObjCMethodDecl
*BestMethod
= SemaRef
.SelectBestMethod(
3026 Sel
, ArgsIn
, Method
->isInstanceMethod(), Methods
))
3027 Method
= BestMethod
;
3033 ObjCInterfaceDecl
*ClassDecl
= nullptr;
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);
3043 Method
= LookupMethodInQualifiedType(Sel
, QIdTy
, false);
3044 if (Method
&& SemaRef
.DiagnoseUseOfDecl(Method
, SelectorSlotLocs
))
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();
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;
3056 if (SemaRef
.RequireCompleteType(
3057 Loc
, OCIType
->getPointeeType(),
3058 getLangOpts().ObjCAutoRefCount
3059 ? diag::err_arc_receiver_forward_instance
3060 : diag::warn_receiver_forward_instance
,
3062 if (getLangOpts().ObjCAutoRefCount
)
3065 forwardClass
= OCIType
->getInterfaceDecl();
3066 Diag(Receiver
? Receiver
->getBeginLoc() : SuperLoc
,
3067 diag::note_receiver_is_id
);
3070 Method
= ClassDecl
->lookupInstanceMethod(Sel
);
3074 // Search protocol qualifiers.
3075 Method
= LookupMethodInQualifiedType(Sel
, OCIType
, true);
3078 // If we have implementations in scope, check "private" methods.
3079 Method
= ClassDecl
->lookupPrivateMethod(Sel
);
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());
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()) {
3093 SmallVector
<ObjCMethodDecl
*, 4> Methods
;
3094 CollectMultipleMethodsInGlobalPool(Sel
, Methods
,
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];
3102 if (ObjCMethodDecl
*BestMethod
= SemaRef
.SelectBestMethod(
3103 Sel
, ArgsIn
, Method
->isInstanceMethod(), Methods
))
3104 Method
= BestMethod
;
3106 AreMultipleMethodsInGlobalPool(Sel
, Method
,
3107 SourceRange(LBracLoc
, RBracLoc
),
3108 true/*receiverIdOrClass*/,
3111 if (Method
&& !forwardClass
)
3112 Diag(SelLoc
, diag::warn_maynot_respond
)
3113 << OCIType
->getInterfaceDecl()->getIdentifier()
3119 SemaRef
.DiagnoseUseOfDecl(Method
, SelectorSlotLocs
, forwardClass
))
3122 // Reject other random receiver types (e.g. structs).
3123 Diag(Loc
, diag::err_bad_receiver_type
) << ReceiverType
<< RecRange
;
3129 FunctionScopeInfo
*DIFunctionScopeInfo
=
3130 (Method
&& Method
->getMethodFamily() == OMF_init
)
3131 ? SemaRef
.getEnclosingFunction()
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();
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
)) {
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()));
3155 Diag(Method
->getLocation(), diag::note_direct_method_declared_at
)
3156 << Method
->getDeclName();
3159 if (SuperLoc
.isValid()) {
3162 Diag(SuperLoc
, diag::err_messaging_super_with_direct_method
);
3163 if (ReceiverType
->isObjCClassType()) {
3164 Builder
.AddFixItHint(FixItHint::CreateReplacement(
3165 SuperLoc
, Method
->getClassInterface()->getName()));
3167 Builder
.AddFixItHint(FixItHint::CreateReplacement(SuperLoc
, "self"));
3170 Diag(Method
->getLocation(), diag::note_direct_method_declared_at
)
3171 << Method
->getDeclName();
3173 } else if (ReceiverType
->isObjCIdType() && !isImplicit
) {
3174 Diag(Receiver
->getExprLoc(), diag::warn_messaging_unqualified_id
);
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;
3195 if (!isDesignatedInitChain
) {
3196 const ObjCMethodDecl
*InitMethod
= nullptr;
3197 auto *CurMD
= SemaRef
.getCurMethodDecl();
3198 assert(CurMD
&& "Current method declaration should not be null");
3200 CurMD
->isDesignatedInitializerForTheInterface(&InitMethod
);
3201 assert(isDesignated
&& InitMethod
);
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
);
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
);
3217 DIFunctionScopeInfo
->ObjCWarnForNoInitDelegation
= false;
3221 // Check the message arguments.
3222 unsigned NumArgs
= ArgsIn
.size();
3223 Expr
**Args
= ArgsIn
.data();
3224 QualType ReturnType
;
3225 ExprValueKind VK
= VK_PRValue
;
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
))
3234 if (Method
&& !Method
->getReturnType()->isVoidType() &&
3235 SemaRef
.RequireCompleteType(
3236 LBracLoc
, Method
->getReturnType(),
3237 diag::err_illegal_message_expr_incomplete_type
))
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());
3248 checkInitMethod(Method
, ReceiverType
);
3255 case OMF_mutableCopy
:
3258 case OMF_initialize
:
3264 case OMF_autorelease
:
3265 case OMF_retainCount
:
3266 Diag(SelLoc
, diag::err_arc_illegal_explicit_message
)
3270 case OMF_performSelector
:
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
=
3276 LookupInstanceMethodInGlobalPool(ArgSel
,
3277 SelExp
->getSourceRange());
3280 LookupFactoryMethodInGlobalPool(ArgSel
,
3281 SelExp
->getSourceRange());
3283 ObjCMethodFamily SelFamily
= SelMethod
->getMethodFamily();
3284 switch (SelFamily
) {
3287 case OMF_mutableCopy
:
3290 // Issue error, unless ns_returns_not_retained.
3291 if (!SelMethod
->hasAttr
<NSReturnsNotRetainedAttr
>()) {
3292 // selector names a +1 method
3294 diag::err_arc_perform_selector_retains
);
3295 Diag(SelMethod
->getLocation(), diag::note_method_declared_at
)
3296 << SelMethod
->getDeclName();
3300 // +0 call. OK. unless ns_returns_retained.
3301 if (SelMethod
->hasAttr
<NSReturnsRetainedAttr
>()) {
3302 // selector names a +1 method
3304 diag::err_arc_perform_selector_retains
);
3305 Diag(SelMethod
->getLocation(), diag::note_method_declared_at
)
3306 << SelMethod
->getDeclName();
3312 // error (may leak).
3313 Diag(SelLoc
, diag::warn_arc_perform_selector_leaks
);
3314 Diag(Args
[0]->getExprLoc(), diag::note_used_here
);
3321 DiagnoseCStringFormatDirectiveInObjCAPI(SemaRef
, Method
, Sel
, Args
, NumArgs
);
3323 // Construct the appropriate ObjCMessageExpr instance.
3324 ObjCMessageExpr
*Result
;
3325 if (SuperLoc
.isValid())
3326 Result
= ObjCMessageExpr::Create(
3327 Context
, ReturnType
, VK
, LBracLoc
, SuperLoc
, /*IsInstanceSuper=*/true,
3328 ReceiverType
, Sel
, SelectorLocs
, Method
, ArrayRef(Args
, NumArgs
),
3329 RBracLoc
, isImplicit
);
3331 Result
= ObjCMessageExpr::Create(
3332 Context
, ReturnType
, VK
, LBracLoc
, Receiver
, Sel
, SelectorLocs
, Method
,
3333 ArrayRef(Args
, NumArgs
), RBracLoc
, isImplicit
);
3335 checkCocoaAPI(SemaRef
, Result
);
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;
3349 Context
.getObjCInterfaceType(CurMeth
->getClassInterface());
3354 checkFoundationAPI(SemaRef
, SelLoc
, Method
, ArrayRef(Args
, NumArgs
),
3355 ReceiverType
, IsClassObjectCall
);
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);
3373 // In ARC, check for message sends which are likely to introduce
3375 checkRetainCycles(Result
);
3378 if (getLangOpts().ObjCWeak
) {
3379 if (!isImplicit
&& Method
) {
3380 if (const ObjCPropertyDecl
*Prop
= Method
->findPropertyDecl()) {
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
,
3388 SemaRef
.getCurFunction()->recordUseOfWeak(Result
, Prop
);
3393 CheckObjCCircularContainer(Result
);
3395 return SemaRef
.MaybeBindToTemporary(Result
);
3398 static void RemoveSelectorFromWarningCache(SemaObjC
&S
, Expr
*Arg
) {
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
);
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().
3412 ExprResult
SemaObjC::ActOnInstanceMessage(Scope
*S
, Expr
*Receiver
,
3413 Selector Sel
, SourceLocation LBracLoc
,
3414 ArrayRef
<SourceLocation
> SelectorLocs
,
3415 SourceLocation RBracLoc
,
3416 MultiExprArg Args
) {
3417 ASTContext
&Context
= getASTContext();
3421 // A ParenListExpr can show up while doing error recovery with invalid code.
3422 if (isa
<ParenListExpr
>(Receiver
)) {
3424 SemaRef
.MaybeConvertParenListExprToParenExpr(S
, Receiver
);
3425 if (Result
.isInvalid()) return ExprError();
3426 Receiver
= Result
.get();
3429 if (RespondsToSelectorSel
.isNull()) {
3430 IdentifierInfo
*SelectorId
= &Context
.Idents
.get("respondsToSelector");
3431 RespondsToSelectorSel
= Context
.Selectors
.getUnarySelector(SelectorId
);
3433 if (Sel
== RespondsToSelectorSel
)
3434 RemoveSelectorFromWarningCache(*this, Args
[0]);
3436 return BuildInstanceMessage(Receiver
, Receiver
->getType(),
3437 /*SuperLoc=*/SourceLocation(), Sel
,
3438 /*Method=*/nullptr, LBracLoc
, SelectorLocs
,
3442 enum ARCConversionTypeClass
{
3443 /// int, void, struct A
3449 /// id*, id***, void (^*)(),
3450 ACTC_indirectRetainable
,
3452 /// void* might be a normal C type, or it might a CF type.
3459 static bool isAnyRetainable(ARCConversionTypeClass ACTC
) {
3460 return (ACTC
== ACTC_retainable
||
3461 ACTC
== ACTC_coreFoundation
||
3462 ACTC
== ACTC_voidPtr
);
3465 static bool isAnyCLike(ARCConversionTypeClass ACTC
) {
3466 return ACTC
== ACTC_none
||
3467 ACTC
== ACTC_voidPtr
||
3468 ACTC
== ACTC_coreFoundation
;
3471 static ARCConversionTypeClass
classifyTypeForARCConversion(QualType type
) {
3472 bool isIndirect
= false;
3474 // Ignore an outermost reference type.
3475 if (const ReferenceType
*ref
= type
->getAs
<ReferenceType
>()) {
3476 type
= ref
->getPointeeType();
3480 // Drill through pointers and arrays recursively.
3482 if (const PointerType
*ptr
= type
->getAs
<PointerType
>()) {
3483 type
= ptr
->getPointeeType();
3485 // The first level of pointer may be the innermost pointer on a CF type.
3487 if (type
->isVoidType()) return ACTC_voidPtr
;
3488 if (type
->isRecordType()) return ACTC_coreFoundation
;
3490 } else if (const ArrayType
*array
= type
->getAsArrayTypeUnsafe()) {
3491 type
= QualType(array
->getElementType()->getBaseElementTypeUnsafe(), 0);
3499 if (type
->isObjCARCBridgableType())
3500 return ACTC_indirectRetainable
;
3504 if (type
->isObjCARCBridgableType())
3505 return ACTC_retainable
;
3511 /// A result from the cast checker.
3513 /// Cannot be casted.
3516 /// Can be safely retained or not retained.
3519 /// Can be casted at +0.
3522 /// Can be casted at +1.
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
;
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
> {
3535 typedef StmtVisitor
<ARCCastChecker
, ACCResult
> super
;
3537 ASTContext
&Context
;
3538 ARCConversionTypeClass SourceClass
;
3539 ARCConversionTypeClass TargetClass
;
3542 static bool isCFType(QualType type
) {
3543 // Someday this can use ns_bridged. For now, it has to do this.
3544 return type
->isCARCBridgableType();
3548 ARCCastChecker(ASTContext
&Context
, ARCConversionTypeClass source
,
3549 ARCConversionTypeClass target
, bool diagnose
)
3550 : Context(Context
), SourceClass(source
), TargetClass(target
),
3551 Diagnose(diagnose
) {}
3554 ACCResult
Visit(Expr
*e
) {
3555 return super::Visit(e
->IgnoreParens());
3558 ACCResult
VisitStmt(Stmt
*s
) {
3562 /// Null pointer constants can be casted however you please.
3563 ACCResult
VisitExpr(Expr
*e
) {
3564 if (e
->isNullPointerConstant(Context
, Expr::NPC_ValueDependentIsNotNull
))
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
;
3578 /// Look through certain implicit and explicit casts.
3579 ACCResult
VisitCastExpr(CastExpr
*e
) {
3580 switch (e
->getCastKind()) {
3581 case CK_NullToPointer
:
3585 case CK_LValueToRValue
:
3587 case CK_CPointerToObjCPointerCast
:
3588 case CK_BlockPointerToObjCPointerCast
:
3589 case CK_AnyPointerToBlockPointerCast
:
3590 return Visit(e
->getSubExpr());
3597 /// Look through unary extension.
3598 ACCResult
VisitUnaryExtension(UnaryOperator
*e
) {
3599 return Visit(e
->getSubExpr());
3602 /// Ignore the LHS of a comma operator.
3603 ACCResult
VisitBinComma(BinaryOperator
*e
) {
3604 return Visit(e
->getRHS());
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()));
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());
3620 /// Statement expressions are okay if their result expression is okay.
3621 ACCResult
VisitStmtExpr(StmtExpr
*e
) {
3622 return Visit(e
->getSubStmt()->body_back());
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
) &&
3632 !var
->hasDefinition(Context
) &&
3633 var
->getType().isConstQualified()) {
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()))
3640 return ACC_plusZero
;
3647 /// Some calls are okay.
3648 ACCResult
VisitCallExpr(CallExpr
*e
) {
3649 if (FunctionDecl
*fn
= e
->getDirectCallee())
3650 if (ACCResult result
= checkCallToFunction(fn
))
3653 return super::VisitCallExpr(e
);
3656 ACCResult
checkCallToFunction(FunctionDecl
*fn
) {
3657 // Require a CF*Ref return type.
3658 if (!isCFType(fn
->getReturnType()))
3661 if (!isAnyRetainable(TargetClass
))
3664 // Honor an explicit 'not retained' attribute.
3665 if (fn
->hasAttr
<CFReturnsNotRetainedAttr
>())
3666 return ACC_plusZero
;
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
3675 // Recognize this specific builtin function, which is used by CFSTR.
3676 unsigned builtinID
= fn
->getBuiltinID();
3677 if (builtinID
== Builtin::BI__builtin___CFStringMakeConstantString
)
3680 // Otherwise, don't do anything implicit with an unaudited function.
3681 if (!fn
->hasAttr
<CFAuditedTransferAttr
>())
3684 // Otherwise, it's +0 unless it follows the create convention.
3685 if (ento::coreFoundation::followsCreateRule(fn
))
3686 return Diagnose
? ACC_plusOne
3687 : ACC_invalid
; // ACC_plusOne if we start accepting this
3689 return ACC_plusZero
;
3692 ACCResult
VisitObjCMessageExpr(ObjCMessageExpr
*e
) {
3693 return checkCallToMethod(e
->getMethodDecl());
3696 ACCResult
VisitObjCPropertyRefExpr(ObjCPropertyRefExpr
*e
) {
3697 ObjCMethodDecl
*method
;
3698 if (e
->isExplicitProperty())
3699 method
= e
->getExplicitProperty()->getGetterMethodDecl();
3701 method
= e
->getImplicitPropertyGetter();
3702 return checkCallToMethod(method
);
3705 ACCResult
checkCallToMethod(ObjCMethodDecl
*method
) {
3706 if (!method
) return ACC_invalid
;
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()))
3714 // If the method is explicitly marked not-retained, it's +0.
3715 if (method
->hasAttr
<CFReturnsNotRetainedAttr
>())
3716 return ACC_plusZero
;
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
>())
3723 switch (method
->getSelector().getMethodFamily()) {
3726 case OMF_mutableCopy
:
3731 // Otherwise, treat it as +0.
3732 return ACC_plusZero
;
3736 } // end anonymous namespace
3738 bool SemaObjC::isKnownName(StringRef name
) {
3739 ASTContext
&Context
= getASTContext();
3742 LookupResult
R(SemaRef
, &Context
.Idents
.get(name
), SourceLocation(),
3743 Sema::LookupOrdinaryName
);
3744 return SemaRef
.LookupName(R
, SemaRef
.TUScope
, false);
3747 template <typename DiagBuilderT
>
3748 static void addFixitForObjCARCConversion(
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.
3754 case CheckedConversionKind::Implicit
:
3755 case CheckedConversionKind::ForBuiltinOverloadedOp
:
3756 case CheckedConversionKind::CStyleCast
:
3757 case CheckedConversionKind::OtherCast
:
3759 case CheckedConversionKind::FunctionalCast
:
3764 if (CCK
== CheckedConversionKind::OtherCast
) {
3765 if (const CXXNamedCastExpr
*NCE
= dyn_cast
<CXXNamedCastExpr
>(realCast
)) {
3766 SourceRange
range(NCE
->getOperatorLoc(),
3767 NCE
->getAngleBrackets().getEnd());
3768 SmallString
<32> BridgeCall
;
3770 SourceManager
&SM
= S
.getSourceManager();
3771 char PrevChar
= *SM
.getCharacterData(range
.getBegin().getLocWithOffset(-1));
3772 if (Lexer::isAsciiIdentifierContinueChar(PrevChar
, S
.getLangOpts()))
3775 BridgeCall
+= CFBridgeName
;
3776 DiagB
.AddFixItHint(FixItHint::CreateReplacement(range
, BridgeCall
));
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();
3786 SmallString
<32> BridgeCall
;
3788 SourceManager
&SM
= S
.getSourceManager();
3789 char PrevChar
= *SM
.getCharacterData(range
.getBegin().getLocWithOffset(-1));
3790 if (Lexer::isAsciiIdentifierContinueChar(PrevChar
, S
.getLangOpts()))
3793 BridgeCall
+= CFBridgeName
;
3795 if (isa
<ParenExpr
>(castedE
)) {
3796 DiagB
.AddFixItHint(FixItHint::CreateInsertion(range
.getBegin(),
3800 DiagB
.AddFixItHint(FixItHint::CreateInsertion(range
.getBegin(),
3802 DiagB
.AddFixItHint(FixItHint::CreateInsertion(
3803 S
.getLocForEndOfToken(range
.getEnd()),
3809 if (CCK
== CheckedConversionKind::CStyleCast
) {
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();
3817 SourceRange
Range(NCE
->getOperatorLoc(),
3818 NCE
->getAngleBrackets().getEnd());
3819 DiagB
.AddFixItHint(FixItHint::CreateReplacement(Range
, castCode
));
3822 std::string castCode
= "(";
3823 castCode
+= bridgeKeyword
;
3824 castCode
+= castType
.getAsString();
3826 Expr
*castedE
= castExpr
->IgnoreImpCasts();
3827 SourceRange range
= castedE
->getSourceRange();
3828 if (isa
<ParenExpr
>(castedE
)) {
3829 DiagB
.AddFixItHint(FixItHint::CreateInsertion(range
.getBegin(),
3833 DiagB
.AddFixItHint(FixItHint::CreateInsertion(range
.getBegin(),
3835 DiagB
.AddFixItHint(FixItHint::CreateInsertion(
3836 S
.getLocForEndOfToken(range
.getEnd()),
3842 template <typename T
>
3843 static 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
>())
3858 static 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
))
3865 T
= TDNDecl
->getUnderlyingType();
3870 static void diagnoseObjCARCConversion(Sema
&S
, SourceRange castRange
,
3872 ARCConversionTypeClass castACTC
,
3873 Expr
*castExpr
, Expr
*realCast
,
3874 ARCConversionTypeClass exprACTC
,
3875 CheckedConversionKind CCK
) {
3876 SourceLocation loc
=
3877 (castRange
.isValid() ? castRange
.getBegin() : castExpr
->getExprLoc());
3879 if (S
.makeUnavailableInSystemHeader(loc
,
3880 UnavailableAttr::IR_ARCForbiddenConversion
))
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
)))
3893 unsigned srcKind
= 0;
3896 case ACTC_coreFoundation
:
3898 srcKind
= (castExprType
->isPointerType() ? 1 : 0);
3900 case ACTC_retainable
:
3901 srcKind
= (castExprType
->isBlockPointerType() ? 2 : 3);
3903 case ACTC_indirectRetainable
:
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
;
3912 unsigned convKindForDiag
= Sema::isCast(CCK
) ? 0 : 1;
3914 // Bridge from an ARC type to a CF type.
3915 if (castACTC
== ACTC_retainable
&& isAnyRetainable(exprACTC
)) {
3917 S
.Diag(loc
, diag::err_arc_cast_requires_bridge
)
3919 << 2 // of C pointer type
3921 << unsigned(castType
->isBlockPointerType()) // to ObjC|block type
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
)
3931 auto DiagB
= (CCK
!= CheckedConversionKind::OtherCast
)
3932 ? S
.Diag(noteLoc
, diag::note_arc_bridge
)
3933 : S
.Diag(noteLoc
, diag::note_arc_cstyle_bridge
);
3935 addFixitForObjCARCConversion(S
, DiagB
, CCK
, afterLParen
,
3936 castType
, castExpr
, realCast
, "__bridge ",
3939 if (CreateRule
!= ACC_plusZero
)
3941 auto DiagB
= (CCK
== CheckedConversionKind::OtherCast
&& !br
)
3942 ? S
.Diag(noteLoc
, diag::note_arc_cstyle_bridge_transfer
)
3944 : S
.Diag(br
? castExpr
->getExprLoc() : noteLoc
,
3945 diag::note_arc_bridge_transfer
)
3946 << castExprType
<< br
;
3948 addFixitForObjCARCConversion(S
, DiagB
, CCK
, afterLParen
,
3949 castType
, castExpr
, realCast
, "__bridge_transfer ",
3950 br
? "CFBridgingRelease" : nullptr);
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
)
3961 << unsigned(castExprType
->isBlockPointerType()) // of ObjC|block type
3963 << 2 // to C pointer type
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
)
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 ",
3979 if (CreateRule
!= ACC_plusZero
)
3981 auto DiagB
= (CCK
== CheckedConversionKind::OtherCast
&& !br
)
3982 ? S
.Diag(noteLoc
, diag::note_arc_cstyle_bridge_retained
)
3984 : S
.Diag(br
? castExpr
->getExprLoc() : noteLoc
,
3985 diag::note_arc_bridge_retained
)
3988 addFixitForObjCARCConversion(S
, DiagB
, CCK
, afterLParen
,
3989 castType
, castExpr
, realCast
, "__bridge_retained ",
3990 br
? "CFBridgingRetain" : nullptr);
3996 S
.Diag(loc
, diag::err_arc_mismatched_cast
)
3998 << srcKind
<< castExprType
<< castType
3999 << castRange
<< castExpr
->getSourceRange();
4002 template <typename TB
>
4003 static bool CheckObjCBridgeNSCast(Sema
&S
, QualType castType
, Expr
*castExpr
,
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"))
4015 // Check for an existing type with this name.
4016 LookupResult
R(S
, DeclarationName(Parm
), SourceLocation(),
4017 Sema::LookupOrdinaryName
);
4018 if (S
.LookupName(R
, S
.TUScope
)) {
4019 NamedDecl
*Target
= R
.getFoundDecl();
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
)))
4030 S
.Diag(castExpr
->getBeginLoc(), diag::warn_objc_invalid_bridge
)
4031 << T
<< Target
->getName() << castType
->getPointeeType();
4033 } else if (castType
->isObjCIdType() ||
4034 (S
.Context
.ObjCObjectAdoptsQTypeProtocols(
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.
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
);
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
);
4060 T
= TDNDecl
->getUnderlyingType();
4065 template <typename TB
>
4066 static bool CheckObjCBridgeCFCast(Sema
&S
, QualType castType
, Expr
*castExpr
,
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"))
4078 NamedDecl
*Target
= nullptr;
4079 // Check for an existing type with this name.
4080 LookupResult
R(S
, DeclarationName(Parm
), SourceLocation(),
4081 Sema::LookupOrdinaryName
);
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
)))
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
);
4100 } else if (castExpr
->getType()->isObjCIdType() ||
4101 (S
.Context
.QIdProtocolsAdoptObjCObjectProtocols(
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.
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
);
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
);
4124 S
.Diag(Target
->getBeginLoc(), diag::note_declared_at
);
4129 T
= TDNDecl
->getUnderlyingType();
4134 void SemaObjC::CheckTollFreeBridgeCast(QualType castType
, Expr
*castExpr
) {
4135 if (!getLangOpts().ObjC
)
4137 // warn in presence of __bridge casting to or from a toll free bridge cast.
4138 ARCConversionTypeClass exprACTC
= classifyTypeForARCConversion(castExpr
->getType());
4139 ARCConversionTypeClass castACTC
= classifyTypeForARCConversion(castType
);
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
)
4146 bool HasObjCBridgeMutableAttr
;
4147 bool ObjCBridgeMutableAttrWillNotWarn
=
4148 CheckObjCBridgeNSCast
<ObjCBridgeMutableAttr
>(
4149 SemaRef
, castType
, castExpr
, HasObjCBridgeMutableAttr
, false);
4150 if (ObjCBridgeMutableAttrWillNotWarn
&& HasObjCBridgeMutableAttr
)
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);
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
)
4166 bool HasObjCBridgeMutableAttr
;
4167 bool ObjCBridgeMutableAttrWillNotWarn
=
4168 CheckObjCBridgeCFCast
<ObjCBridgeMutableAttr
>(
4169 SemaRef
, castType
, castExpr
, HasObjCBridgeMutableAttr
, false);
4170 if (ObjCBridgeMutableAttrWillNotWarn
&& HasObjCBridgeMutableAttr
)
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);
4182 void SemaObjC::CheckObjCBridgeRelatedCast(QualType castType
, Expr
*castExpr
) {
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();
4189 else if (PRE
->isImplicitProperty()) {
4190 if (ObjCMethodDecl
*Getter
= PRE
->getImplicitPropertyGetter())
4191 SrcType
= Getter
->getReturnType();
4195 ARCConversionTypeClass srcExprACTC
= classifyTypeForARCConversion(SrcType
);
4196 ARCConversionTypeClass castExprACTC
= classifyTypeForARCConversion(castType
);
4197 if (srcExprACTC
!= ACTC_retainable
|| castExprACTC
!= ACTC_coreFoundation
)
4199 CheckObjCBridgeRelatedConversions(castExpr
->getBeginLoc(), castType
, SrcType
,
4203 bool SemaObjC::CheckTollFreeBridgeStaticCast(QualType castType
, Expr
*castExpr
,
4205 if (!getLangOpts().ObjC
)
4207 ARCConversionTypeClass exprACTC
=
4208 classifyTypeForARCConversion(castExpr
->getType());
4209 ARCConversionTypeClass castACTC
= classifyTypeForARCConversion(castType
);
4210 if ((castACTC
== ACTC_retainable
&& exprACTC
== ACTC_coreFoundation
) ||
4211 (castACTC
== ACTC_coreFoundation
&& exprACTC
== ACTC_retainable
)) {
4212 CheckTollFreeBridgeCast(castType
, castExpr
);
4213 Kind
= (castACTC
== ACTC_coreFoundation
) ? CK_BitCast
4214 : CK_CPointerToObjCPointerCast
;
4220 bool SemaObjC::checkObjCBridgeRelatedComponents(
4221 SourceLocation Loc
, QualType DestType
, QualType SrcType
,
4222 ObjCInterfaceDecl
*&RelatedClass
, ObjCMethodDecl
*&ClassMethod
,
4223 ObjCMethodDecl
*&InstanceMethod
, TypedefNameDecl
*&TDNDecl
, bool CfToNs
,
4225 ASTContext
&Context
= getASTContext();
4226 QualType T
= CfToNs
? SrcType
: DestType
;
4227 ObjCBridgeRelatedAttr
*ObjCBAttr
= ObjCBridgeRelatedAttrFromType(T
, TDNDecl
);
4231 IdentifierInfo
*RCId
= ObjCBAttr
->getRelatedClass();
4232 IdentifierInfo
*CMId
= ObjCBAttr
->getClassMethod();
4233 IdentifierInfo
*IMId
= ObjCBAttr
->getInstanceMethod();
4236 NamedDecl
*Target
= nullptr;
4237 // Check for an existing type with this name.
4238 LookupResult
R(SemaRef
, DeclarationName(RCId
), SourceLocation(),
4239 Sema::LookupOrdinaryName
);
4240 if (!SemaRef
.LookupName(R
, SemaRef
.TUScope
)) {
4242 Diag(Loc
, diag::err_objc_bridged_related_invalid_class
) << RCId
4243 << SrcType
<< DestType
;
4244 Diag(TDNDecl
->getBeginLoc(), diag::note_declared_at
);
4248 Target
= R
.getFoundDecl();
4249 if (Target
&& isa
<ObjCInterfaceDecl
>(Target
))
4250 RelatedClass
= cast
<ObjCInterfaceDecl
>(Target
);
4253 Diag(Loc
, diag::err_objc_bridged_related_invalid_class_name
) << RCId
4254 << SrcType
<< DestType
;
4255 Diag(TDNDecl
->getBeginLoc(), diag::note_declared_at
);
4257 Diag(Target
->getBeginLoc(), diag::note_declared_at
);
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);
4268 Diag(Loc
, diag::err_objc_bridged_related_known_method
)
4269 << SrcType
<< DestType
<< Sel
<< false;
4270 Diag(TDNDecl
->getBeginLoc(), diag::note_declared_at
);
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
) {
4282 Diag(Loc
, diag::err_objc_bridged_related_known_method
)
4283 << SrcType
<< DestType
<< Sel
<< true;
4284 Diag(TDNDecl
->getBeginLoc(), diag::note_declared_at
);
4292 bool SemaObjC::CheckObjCBridgeRelatedConversions(SourceLocation Loc
,
4297 ASTContext
&Context
= getASTContext();
4298 ARCConversionTypeClass rhsExprACTC
= classifyTypeForARCConversion(SrcType
);
4299 ARCConversionTypeClass lhsExprACTC
= classifyTypeForARCConversion(DestType
);
4300 bool CfToNs
= (rhsExprACTC
== ACTC_coreFoundation
&& lhsExprACTC
== ACTC_retainable
);
4301 bool NsToCf
= (rhsExprACTC
== ACTC_retainable
&& lhsExprACTC
== ACTC_coreFoundation
);
4302 if (!CfToNs
&& !NsToCf
)
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
,
4315 // Implicit conversion from CF to ObjC object is needed.
4318 std::string ExpressionString
= "[";
4319 ExpressionString
+= RelatedClass
->getNameAsString();
4320 ExpressionString
+= " ";
4321 ExpressionString
+= ClassMethod
->getSelector().getAsString();
4322 SourceLocation SrcExprEndLoc
=
4323 SemaRef
.getLocForEndOfToken(SrcExpr
->getEndLoc());
4324 // Provide a fixit: [RelatedClass ClassMethod SrcExpr]
4325 Diag(Loc
, diag::err_objc_bridged_related_known_method
)
4326 << SrcType
<< DestType
<< ClassMethod
->getSelector() << false
4327 << FixItHint::CreateInsertion(SrcExpr
->getBeginLoc(),
4329 << FixItHint::CreateInsertion(SrcExprEndLoc
, "]");
4330 Diag(RelatedClass
->getBeginLoc(), diag::note_declared_at
);
4331 Diag(TDNDecl
->getBeginLoc(), diag::note_declared_at
);
4333 QualType receiverType
= Context
.getObjCInterfaceType(RelatedClass
);
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();
4346 // Implicit conversion from ObjC type to CF object is needed.
4347 if (InstanceMethod
) {
4349 std::string ExpressionString
;
4350 SourceLocation SrcExprEndLoc
=
4351 SemaRef
.getLocForEndOfToken(SrcExpr
->getEndLoc());
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
);
4362 if (ExpressionString
.empty()) {
4363 // Provide a fixit: [ObjectExpr InstanceMethod]
4364 ExpressionString
= " ";
4365 ExpressionString
+= InstanceMethod
->getSelector().getAsString();
4366 ExpressionString
+= "]";
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
);
4373 Diag(RelatedClass
->getBeginLoc(), diag::note_declared_at
);
4374 Diag(TDNDecl
->getBeginLoc(), diag::note_declared_at
);
4376 ExprResult msg
= BuildInstanceMessageImplicit(
4377 SrcExpr
, SrcType
, InstanceMethod
->getLocation(),
4378 InstanceMethod
->getSelector(), InstanceMethod
, {});
4379 SrcExpr
= msg
.get();
4387 SemaObjC::ARCConversionResult
4388 SemaObjC::CheckObjCConversion(SourceRange castRange
, QualType castType
,
4389 Expr
*&castExpr
, CheckedConversionKind CCK
,
4390 bool Diagnose
, bool DiagnoseCFAudited
,
4391 BinaryOperatorKind Opc
) {
4392 ASTContext
&Context
= getASTContext();
4393 QualType castExprType
= castExpr
->getType();
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();
4401 ARCConversionTypeClass exprACTC
= classifyTypeForARCConversion(castExprType
);
4402 ARCConversionTypeClass castACTC
= classifyTypeForARCConversion(effCastType
);
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
&&
4407 (CCK
== CheckedConversionKind::CStyleCast
||
4408 CCK
== CheckedConversionKind::OtherCast
) &&
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
&&
4422 QDT
.getObjCLifetime() != Qualifiers::OCL_None
) {
4424 SourceLocation loc
= (castRange
.isValid() ? castRange
.getBegin()
4425 : castExpr
->getExprLoc());
4426 Diag(loc
, diag::err_arc_nolifetime_behavior
);
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
)
4439 if (isAnyCLike(exprACTC
) && isAnyCLike(castACTC
)) return ACR_okay
;
4441 // Allow all of these types to be cast to integer types (but not
4443 if (castACTC
== ACTC_none
&& castType
->isIntegralType(Context
))
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
))))
4455 if (castACTC
== ACTC_indirectRetainable
&&
4456 (exprACTC
== ACTC_voidPtr
|| exprACTC
== ACTC_coreFoundation
) &&
4457 SemaRef
.isCast(CCK
))
4460 switch (ARCCastChecker(Context
, exprACTC
, castACTC
, false).Visit(castExpr
)) {
4461 // For invalid casts, fall through.
4465 // Do nothing for both bottom and +0.
4470 // If the result is +1, consume it here.
4472 castExpr
= ImplicitCastExpr::Create(Context
, castExpr
->getType(),
4473 CK_ARCConsumeObject
, castExpr
, nullptr,
4474 VK_PRValue
, FPOptionsOverride());
4475 SemaRef
.Cleanup
.setExprNeedsCleanups(true);
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
;
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"
4489 if (castACTC
== ACTC_retainable
&& exprACTC
== ACTC_none
&&
4490 CheckConversionToObjCLiteral(castType
, castExpr
, Diagnose
))
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
4497 if ((!DiagnoseCFAudited
|| exprACTC
!= ACTC_retainable
||
4498 castACTC
!= ACTC_coreFoundation
) &&
4499 !(exprACTC
== ACTC_voidPtr
&& castACTC
== ACTC_retainable
&&
4500 (Opc
== BO_NE
|| Opc
== BO_EQ
))) {
4502 diagnoseObjCARCConversion(SemaRef
, castRange
, castType
, castACTC
,
4503 castExpr
, castExpr
, exprACTC
, CCK
);
4509 /// Given that we saw an expression with the ARCUnbridgedCastTy
4510 /// placeholder type, complain bitterly.
4511 void SemaObjC::diagnoseARCUnbridgedCast(Expr
*e
) {
4512 // We expect the spurious ImplicitCastExpr to already have been stripped.
4513 assert(!e
->hasPlaceholderType(BuiltinType::ARCUnbridgedCast
));
4514 CastExpr
*realCast
= cast
<CastExpr
>(e
->IgnoreParens());
4516 SourceRange castRange
;
4518 CheckedConversionKind CCK
;
4520 if (CStyleCastExpr
*cast
= dyn_cast
<CStyleCastExpr
>(realCast
)) {
4521 castRange
= SourceRange(cast
->getLParenLoc(), cast
->getRParenLoc());
4522 castType
= cast
->getTypeAsWritten();
4523 CCK
= CheckedConversionKind::CStyleCast
;
4524 } else if (ExplicitCastExpr
*cast
= dyn_cast
<ExplicitCastExpr
>(realCast
)) {
4525 castRange
= cast
->getTypeInfoAsWritten()->getTypeLoc().getSourceRange();
4526 castType
= cast
->getTypeAsWritten();
4527 CCK
= CheckedConversionKind::OtherCast
;
4529 llvm_unreachable("Unexpected ImplicitCastExpr");
4532 ARCConversionTypeClass castACTC
=
4533 classifyTypeForARCConversion(castType
.getNonReferenceType());
4535 Expr
*castExpr
= realCast
->getSubExpr();
4536 assert(classifyTypeForARCConversion(castExpr
->getType()) == ACTC_retainable
);
4538 diagnoseObjCARCConversion(SemaRef
, castRange
, castType
, castACTC
, castExpr
,
4539 realCast
, ACTC_retainable
, CCK
);
4542 /// stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast
4543 /// type, remove the placeholder cast.
4544 Expr
*SemaObjC::stripARCUnbridgedCast(Expr
*e
) {
4545 assert(e
->hasPlaceholderType(BuiltinType::ARCUnbridgedCast
));
4546 ASTContext
&Context
= getASTContext();
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,
4557 SemaRef
.CurFPFeatureOverrides());
4558 } else if (GenericSelectionExpr
*gse
= dyn_cast
<GenericSelectionExpr
>(e
)) {
4559 assert(!gse
->isResultDependent());
4560 assert(!gse
->isTypePredicate());
4562 unsigned n
= gse
->getNumAssocs();
4563 SmallVector
<Expr
*, 4> subExprs
;
4564 SmallVector
<TypeSourceInfo
*, 4> subTypes
;
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
);
4575 return GenericSelectionExpr::Create(
4576 Context
, gse
->getGenericLoc(), gse
->getControllingExpr(), subTypes
,
4577 subExprs
, gse
->getDefaultLoc(), gse
->getRParenLoc(),
4578 gse
->containsUnexpandedParameterPack(), gse
->getResultIndex());
4580 assert(isa
<ImplicitCastExpr
>(e
) && "bad form of unbridged cast!");
4581 return cast
<ImplicitCastExpr
>(e
)->getSubExpr();
4585 bool SemaObjC::CheckObjCARCUnavailableWeakConversion(QualType castType
,
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();
4603 /// Look for an ObjCReclaimReturnedObject cast and destroy it.
4604 static Expr
*maybeUndoReclaimObject(Expr
*e
) {
4605 Expr
*curExpr
= e
, *prevExpr
= nullptr;
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.
4610 if (auto *pe
= dyn_cast
<ParenExpr
>(curExpr
)) {
4612 curExpr
= pe
->getSubExpr();
4616 if (auto *ce
= dyn_cast
<CastExpr
>(curExpr
)) {
4617 if (auto *ice
= dyn_cast
<ImplicitCastExpr
>(ce
))
4618 if (ice
->getCastKind() == CK_ARCReclaimReturnedObject
) {
4620 return ice
->getSubExpr();
4621 if (auto *pe
= dyn_cast
<ParenExpr
>(prevExpr
))
4622 pe
->setSubExpr(ice
->getSubExpr());
4624 cast
<CastExpr
>(prevExpr
)->setSubExpr(ice
->getSubExpr());
4629 curExpr
= ce
->getSubExpr();
4633 // Break out of the loop if curExpr is neither a Paren nor a Cast.
4640 ExprResult
SemaObjC::BuildObjCBridgedCast(SourceLocation LParenLoc
,
4641 ObjCBridgeCastKind Kind
,
4642 SourceLocation BridgeKeywordLoc
,
4643 TypeSourceInfo
*TSInfo
,
4645 ASTContext
&Context
= getASTContext();
4646 ExprResult SubResult
= SemaRef
.UsualUnaryConversions(SubExpr
);
4647 if (SubResult
.isInvalid()) return ExprError();
4648 SubExpr
= SubResult
.get();
4650 QualType T
= TSInfo
->getType();
4651 QualType FromType
= SubExpr
->getType();
4655 bool MustConsume
= false;
4656 if (T
->isDependentType() || SubExpr
->isTypeDependent()) {
4657 // Okay: we'll build a dependent expression type.
4659 } else if (T
->isObjCARCBridgableType() && FromType
->isCARCBridgableType()) {
4661 CK
= (T
->isBlockPointerType() ? CK_AnyPointerToBlockPointerCast
4662 : CK_CPointerToObjCPointerCast
);
4667 case OBC_BridgeRetained
: {
4668 bool br
= isKnownName("CFBridgingRelease");
4669 Diag(BridgeKeywordLoc
, diag::err_arc_bridge_cast_wrong_kind
)
4672 << (T
->isBlockPointerType()? 1 : 0)
4674 << SubExpr
->getSourceRange()
4676 Diag(BridgeKeywordLoc
, diag::note_arc_bridge
)
4677 << FixItHint::CreateReplacement(BridgeKeywordLoc
, "__bridge");
4678 Diag(BridgeKeywordLoc
, diag::note_arc_bridge_transfer
)
4680 << FixItHint::CreateReplacement(BridgeKeywordLoc
,
4681 br
? "CFBridgingRelease "
4682 : "__bridge_transfer ");
4688 case OBC_BridgeTransfer
:
4689 // We must consume the Objective-C object produced by the cast.
4693 } else if (T
->isCARCBridgableType() && FromType
->isObjCARCBridgableType()) {
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
);
4703 case OBC_BridgeRetained
:
4704 // Produce the object before casting it.
4705 SubExpr
= ImplicitCastExpr::Create(Context
, FromType
, CK_ARCProduceObject
,
4706 SubExpr
, nullptr, VK_PRValue
,
4707 FPOptionsOverride());
4710 case OBC_BridgeTransfer
: {
4711 bool br
= isKnownName("CFBridgingRetain");
4712 Diag(BridgeKeywordLoc
, diag::err_arc_bridge_cast_wrong_kind
)
4713 << (FromType
->isBlockPointerType()? 1 : 0)
4717 << SubExpr
->getSourceRange()
4720 Diag(BridgeKeywordLoc
, diag::note_arc_bridge
)
4721 << FixItHint::CreateReplacement(BridgeKeywordLoc
, "__bridge ");
4722 Diag(BridgeKeywordLoc
, diag::note_arc_bridge_retained
)
4724 << FixItHint::CreateReplacement(BridgeKeywordLoc
,
4725 br
? "CFBridgingRetain " : "__bridge_retained");
4732 Diag(LParenLoc
, diag::err_arc_bridge_cast_incompatible
)
4733 << FromType
<< T
<< Kind
4734 << SubExpr
->getSourceRange()
4735 << TSInfo
->getTypeLoc().getSourceRange();
4739 Expr
*Result
= new (Context
) ObjCBridgedCastExpr(LParenLoc
, Kind
, CK
,
4744 SemaRef
.Cleanup
.setExprNeedsCleanups(true);
4745 Result
= ImplicitCastExpr::Create(Context
, T
, CK_ARCConsumeObject
, Result
,
4746 nullptr, VK_PRValue
, FPOptionsOverride());
4752 ExprResult
SemaObjC::ActOnObjCBridgedCast(Scope
*S
, SourceLocation LParenLoc
,
4753 ObjCBridgeCastKind Kind
,
4754 SourceLocation BridgeKeywordLoc
,
4756 SourceLocation RParenLoc
,
4758 ASTContext
&Context
= getASTContext();
4759 TypeSourceInfo
*TSInfo
= nullptr;
4760 QualType T
= SemaRef
.GetTypeFromParser(Type
, &TSInfo
);
4761 if (Kind
== OBC_Bridge
)
4762 CheckTollFreeBridgeCast(T
, SubExpr
);
4764 TSInfo
= Context
.getTrivialTypeSourceInfo(T
, LParenLoc
);
4765 return BuildObjCBridgedCast(LParenLoc
, Kind
, BridgeKeywordLoc
, TSInfo
,
4769 DeclResult
SemaObjC::LookupIvarInObjCMethod(LookupResult
&Lookup
, Scope
*S
,
4770 IdentifierInfo
*II
) {
4771 SourceLocation Loc
= Lookup
.getNameLoc();
4772 ObjCMethodDecl
*CurMethod
= SemaRef
.getCurMethodDecl();
4774 // Check for error condition which is already reported.
4776 return DeclResult(true);
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.
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();
4791 LookForIvars
= true;
4792 else if (IsClassMethod
)
4793 LookForIvars
= false;
4795 LookForIvars
= (Lookup
.isSingleResult() &&
4796 Lookup
.getFoundDecl()->isDefinedOutsideFunctionOrMethod());
4797 ObjCInterfaceDecl
*IFace
= nullptr;
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);
4809 // Diagnose the use of an ivar outside of the declaring class.
4810 if (IV
->getAccessControl() == ObjCIvarDecl::Private
&&
4811 !declaresSameEntity(ClassDeclared
, IFace
) &&
4812 !getLangOpts().DebuggerSupport
)
4813 Diag(Loc
, diag::err_private_ivar_access
) << IV
->getDeclName();
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();
4828 } else if (Lookup
.isSingleResult() &&
4829 Lookup
.getFoundDecl()->isDefinedOutsideFunctionOrMethod()) {
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);
4838 // Didn't encounter an error, didn't find an ivar.
4839 return DeclResult(false);
4842 ExprResult
SemaObjC::LookupInObjCMethod(LookupResult
&Lookup
, Scope
*S
,
4844 bool AllowBuiltinCreation
) {
4845 // FIXME: Integrate this lookup step into LookupParsedName.
4846 DeclResult Ivar
= LookupIvarInObjCMethod(Lookup
, S
, II
);
4847 if (Ivar
.isInvalid())
4849 if (Ivar
.isUsable())
4850 return BuildIvarRefExpr(S
, Lookup
.getNameLoc(),
4851 cast
<ObjCIvarDecl
>(Ivar
.get()));
4853 if (Lookup
.empty() && II
&& AllowBuiltinCreation
)
4854 SemaRef
.LookupBuiltin(Lookup
);
4856 // Sentinel value saying that we didn't do anything special.
4857 return ExprResult(false);
4860 ExprResult
SemaObjC::BuildIvarRefExpr(Scope
*S
, SourceLocation Loc
,
4862 ASTContext
&Context
= getASTContext();
4863 ObjCMethodDecl
*CurMethod
= SemaRef
.getCurMethodDecl();
4864 assert(CurMethod
&& CurMethod
->isInstanceMethod() &&
4865 "should not reference ivar from this context");
4867 ObjCInterfaceDecl
*IFace
= CurMethod
->getClassInterface();
4868 assert(IFace
&& "should not reference ivar from this context");
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())
4875 // Check if referencing a field with __attribute__((deprecated)).
4876 if (SemaRef
.DiagnoseUseOfDecl(IV
, Loc
))
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())
4893 SelfExpr
= SemaRef
.DefaultLvalueConversion(SelfExpr
.get());
4894 if (SelfExpr
.isInvalid())
4897 SemaRef
.MarkAnyDeclReferenced(Loc
, IV
, true);
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();
4904 ObjCIvarRefExpr
*Result
= new (Context
)
4905 ObjCIvarRefExpr(IV
, IV
->getUsageType(SelfExpr
.get()->getType()), Loc
,
4906 IV
->getLocation(), SelfExpr
.get(), true, true);
4908 if (IV
->getType().getObjCLifetime() == Qualifiers::OCL_Weak
) {
4909 if (!SemaRef
.isUnevaluatedContext() &&
4910 !getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak
, Loc
))
4911 SemaRef
.getCurFunction()->recordUseOfWeak(Result
);
4913 if (getLangOpts().ObjCAutoRefCount
&& !SemaRef
.isUnevaluatedContext())
4914 if (const BlockDecl
*BD
= SemaRef
.CurContext
->getInnermostBlockDecl())
4915 SemaRef
.ImplicitlyRetainedSelfLocs
.push_back({Loc
, BD
});
4920 QualType
SemaObjC::FindCompositeObjCPointerType(ExprResult
&LHS
,
4922 SourceLocation QuestionLoc
) {
4923 ASTContext
&Context
= getASTContext();
4924 QualType LHSTy
= LHS
.get()->getType();
4925 QualType RHSTy
= RHS
.get()->getType();
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
);
4936 if (RHSTy
->isObjCClassType() &&
4937 (Context
.hasSameType(LHSTy
, Context
.getObjCClassRedefinitionType()))) {
4938 LHS
= SemaRef
.ImpCastExprToType(LHS
.get(), RHSTy
,
4939 CK_CPointerToObjCPointerCast
);
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
);
4949 if (RHSTy
->isObjCIdType() &&
4950 (Context
.hasSameType(LHSTy
, Context
.getObjCIdRedefinitionType()))) {
4951 LHS
= SemaRef
.ImpCastExprToType(LHS
.get(), RHSTy
,
4952 CK_CPointerToObjCPointerCast
);
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
);
4961 if (Context
.isObjCSelType(RHSTy
) &&
4962 (Context
.hasSameType(LHSTy
, Context
.getObjCSelRedefinitionType()))) {
4963 LHS
= SemaRef
.ImpCastExprToType(LHS
.get(), RHSTy
, CK_BitCast
);
4966 // Check constraints for Objective-C object pointers types.
4967 if (LHSTy
->isObjCObjectPointerType() && RHSTy
->isObjCObjectPointerType()) {
4969 if (Context
.getCanonicalType(LHSTy
) == Context
.getCanonicalType(RHSTy
)) {
4970 // Two identical object pointer types are always compatible.
4973 const ObjCObjectPointerType
*LHSOPT
=
4974 LHSTy
->castAs
<ObjCObjectPointerType
>();
4975 const ObjCObjectPointerType
*RHSOPT
=
4976 RHSTy
->castAs
<ObjCObjectPointerType
>();
4977 QualType compositeType
= LHSTy
;
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.
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.
4990 // FIXME: Consider unifying with 'areComparableObjCPointerTypes'.
4991 // It could return the composite type.
4992 if (!(compositeType
= Context
.areCommonBaseCompatible(LHSOPT
, RHSOPT
))
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
,
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();
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
);
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
;
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();
5035 QualType lhptee
= LHSTy
->castAs
<PointerType
>()->getPointeeType();
5036 QualType rhptee
= RHSTy
->castAs
<ObjCObjectPointerType
>()->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
);
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();
5056 QualType lhptee
= LHSTy
->castAs
<ObjCObjectPointerType
>()->getPointeeType();
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
);
5070 bool SemaObjC::CheckConversionToObjCLiteral(QualType DstType
, Expr
*&Exp
,
5072 if (!getLangOpts().ObjC
)
5075 const ObjCObjectPointerType
*PT
= DstType
->getAs
<ObjCObjectPointerType
>();
5078 const ObjCInterfaceDecl
*ID
= PT
->getInterfaceDecl();
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();
5088 if (auto *SL
= dyn_cast
<StringLiteral
>(SrcExpr
)) {
5089 if (!PT
->isObjCIdType() && !(ID
&& ID
->getIdentifier()->isStr("NSString")))
5091 if (!SL
->isOrdinary())
5095 Diag(SL
->getBeginLoc(), diag::err_missing_atsign_prefix
)
5096 << /*string*/ 0 << FixItHint::CreateInsertion(SL
->getBeginLoc(), "@");
5097 Exp
= BuildObjCStringLiteral(SL
->getBeginLoc(), SL
).get();
5102 if ((isa
<IntegerLiteral
>(SrcExpr
) || isa
<CharacterLiteral
>(SrcExpr
) ||
5103 isa
<FloatingLiteral
>(SrcExpr
) || isa
<ObjCBoolLiteralExpr
>(SrcExpr
) ||
5104 isa
<CXXBoolLiteralExpr
>(SrcExpr
)) &&
5105 !SrcExpr
->isNullPointerConstant(getASTContext(),
5106 Expr::NPC_NeverValueDependent
)) {
5107 if (!ID
|| !ID
->getIdentifier()->isStr("NSNumber"))
5110 Diag(SrcExpr
->getBeginLoc(), diag::err_missing_atsign_prefix
)
5112 << FixItHint::CreateInsertion(SrcExpr
->getBeginLoc(), "@");
5114 BuildObjCNumericLiteral(SrcExpr
->getBeginLoc(), SrcExpr
).get();
5124 /// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals.
5125 ExprResult
SemaObjC::ActOnObjCBoolLiteral(SourceLocation OpLoc
,
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
,
5133 Sema::LookupOrdinaryName
);
5134 if (SemaRef
.LookupName(Result
, SemaRef
.getCurScope()) &&
5135 Result
.isSingleResult()) {
5136 NamedDecl
*ND
= Result
.getFoundDecl();
5137 if (TypedefDecl
*TD
= dyn_cast
<TypedefDecl
>(ND
))
5138 Context
.setBOOLDecl(TD
);
5141 if (Context
.getBOOLDecl())
5142 BoolT
= Context
.getBOOLType();
5143 return new (Context
)
5144 ObjCBoolLiteralExpr(Kind
== tok::kw___objc_yes
, BoolT
, OpLoc
);
5147 ExprResult
SemaObjC::ActOnObjCAvailabilityCheckExpr(
5148 llvm::ArrayRef
<AvailabilitySpec
> AvailSpecs
, SourceLocation AtLoc
,
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
;
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";
5163 if (Spec
== AvailSpecs
.end())
5164 return std::nullopt
;
5165 return Spec
->getVersion();
5168 VersionTuple Version
;
5169 if (auto MaybeVersion
=
5170 FindSpecVersion(Context
.getTargetInfo().getPlatformName()))
5171 Version
= *MaybeVersion
;
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)).
5175 if (FunctionScopeInfo
*Context
= SemaRef
.getCurFunctionAvailabilityContext())
5176 Context
->HasPotentialAvailabilityViolations
= true;
5178 return new (Context
)
5179 ObjCAvailabilityCheckExpr(Version
, AtLoc
, RParen
, Context
.BoolTy
);
5182 /// Prepare a conversion of the given expression to an ObjC object
5184 CastKind
SemaObjC::PrepareCastToObjCObjectPointer(ExprResult
&E
) {
5185 QualType type
= E
.get()->getType();
5186 if (type
->isObjCObjectPointerType()) {
5188 } else if (type
->isBlockPointerType()) {
5189 SemaRef
.maybeExtendBlockObject(E
);
5190 return CK_BlockPointerToObjCPointerCast
;
5192 assert(type
->isPointerType());
5193 return CK_CPointerToObjCPointerCast
;
5197 SemaObjC::ObjCLiteralKind
SemaObjC::CheckLiteralKind(Expr
*FromE
) {
5198 FromE
= FromE
->IgnoreParenImpCasts();
5199 switch (FromE
->getStmtClass()) {
5202 case Stmt::ObjCStringLiteralClass
:
5205 case Stmt::ObjCArrayLiteralClass
:
5208 case Stmt::ObjCDictionaryLiteralClass
:
5209 // "dictionary literal"
5210 return LK_Dictionary
;
5211 case Stmt::BlockExprClass
:
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"
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
)