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