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