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 IdentifierInfo *II[] = {
667 &Context.Idents.get("valueWithBytes"),
668 &Context.Idents.get("objCType")
669 };
670 Selector ValueWithBytesObjCType = Context.Selectors.getSelector(2, II);
671
672 // Look for the appropriate method within NSValue.
673 BoxingMethod = NSValueDecl->lookupClassMethod(ValueWithBytesObjCType);
674 if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) {
675 // Debugger needs to work even if NSValue hasn't been defined.
676 TypeSourceInfo *ReturnTInfo = nullptr;
678 Context, SourceLocation(), SourceLocation(), ValueWithBytesObjCType,
679 NSValuePointer, ReturnTInfo, NSValueDecl,
680 /*isInstance=*/false,
681 /*isVariadic=*/false,
682 /*isPropertyAccessor=*/false,
683 /*isSynthesizedAccessorStub=*/false,
684 /*isImplicitlyDeclared=*/true,
685 /*isDefined=*/false, ObjCImplementationControl::Required,
686 /*HasRelatedResultType=*/false);
687
689
693 &Context.Idents.get("bytes"),
695 /*TInfo=*/nullptr,
696 SC_None, nullptr);
697 Params.push_back(bytes);
698
699 QualType ConstCharType = Context.CharTy.withConst();
703 &Context.Idents.get("type"),
704 Context.getPointerType(ConstCharType),
705 /*TInfo=*/nullptr,
706 SC_None, nullptr);
707 Params.push_back(type);
708
709 M->setMethodParams(Context, Params, std::nullopt);
710 BoxingMethod = M;
711 }
712
713 if (!validateBoxingMethod(*this, Loc, NSValueDecl,
714 ValueWithBytesObjCType, BoxingMethod))
715 return ExprError();
716
717 ValueWithBytesObjCTypeMethod = BoxingMethod;
718 }
719
720 if (!ValueType.isTriviallyCopyableType(Context)) {
721 Diag(Loc, diag::err_objc_non_trivially_copyable_boxed_expression_type)
722 << ValueType << ValueExpr->getSourceRange();
723 return ExprError();
724 }
725
726 BoxingMethod = ValueWithBytesObjCTypeMethod;
727 BoxedType = NSValuePointer;
728 }
729
730 if (!BoxingMethod) {
731 Diag(Loc, diag::err_objc_illegal_boxed_expression_type)
732 << ValueType << ValueExpr->getSourceRange();
733 return ExprError();
734 }
735
736 DiagnoseUseOfDecl(BoxingMethod, Loc);
737
738 ExprResult ConvertedValueExpr;
739 if (ValueType->isObjCBoxableRecordType()) {
741 ConvertedValueExpr = PerformCopyInitialization(IE, ValueExpr->getExprLoc(),
742 ValueExpr);
743 } else {
744 // Convert the expression to the type that the parameter requires.
745 ParmVarDecl *ParamDecl = BoxingMethod->parameters()[0];
747 ParamDecl);
748 ConvertedValueExpr = PerformCopyInitialization(IE, SourceLocation(),
749 ValueExpr);
750 }
751
752 if (ConvertedValueExpr.isInvalid())
753 return ExprError();
754 ValueExpr = ConvertedValueExpr.get();
755
756 ObjCBoxedExpr *BoxedExpr =
757 new (Context) ObjCBoxedExpr(ValueExpr, BoxedType,
758 BoxingMethod, SR);
759 return MaybeBindToTemporary(BoxedExpr);
760}
761
762/// Build an ObjC subscript pseudo-object expression, given that
763/// that's supported by the runtime.
765 Expr *IndexExpr,
766 ObjCMethodDecl *getterMethod,
767 ObjCMethodDecl *setterMethod) {
769
770 // We can't get dependent types here; our callers should have
771 // filtered them out.
772 assert((!BaseExpr->isTypeDependent() && !IndexExpr->isTypeDependent()) &&
773 "base or index cannot have dependent type here");
774
775 // Filter out placeholders in the index. In theory, overloads could
776 // be preserved here, although that might not actually work correctly.
778 if (Result.isInvalid())
779 return ExprError();
780 IndexExpr = Result.get();
781
782 // Perform lvalue-to-rvalue conversion on the base.
784 if (Result.isInvalid())
785 return ExprError();
786 BaseExpr = Result.get();
787
788 // Build the pseudo-object expression.
789 return new (Context) ObjCSubscriptRefExpr(
790 BaseExpr, IndexExpr, Context.PseudoObjectTy, VK_LValue, OK_ObjCSubscript,
791 getterMethod, setterMethod, RB);
792}
793
795 SourceLocation Loc = SR.getBegin();
796
797 if (!NSArrayDecl) {
800 if (!NSArrayDecl) {
801 return ExprError();
802 }
803 }
804
805 // Find the arrayWithObjects:count: method, if we haven't done so already.
809 Sel = NSAPIObj->getNSArraySelector(NSAPI::NSArr_arrayWithObjectsCount);
811 if (!Method && getLangOpts().DebuggerObjCLiteral) {
812 TypeSourceInfo *ReturnTInfo = nullptr;
813 Method = ObjCMethodDecl::Create(
814 Context, SourceLocation(), SourceLocation(), Sel, IdT, ReturnTInfo,
815 Context.getTranslationUnitDecl(), false /*Instance*/,
816 false /*isVariadic*/,
817 /*isPropertyAccessor=*/false, /*isSynthesizedAccessorStub=*/false,
818 /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
821 ParmVarDecl *objects = ParmVarDecl::Create(Context, Method,
824 &Context.Idents.get("objects"),
826 /*TInfo=*/nullptr,
827 SC_None, nullptr);
828 Params.push_back(objects);
832 &Context.Idents.get("cnt"),
834 /*TInfo=*/nullptr, SC_None,
835 nullptr);
836 Params.push_back(cnt);
837 Method->setMethodParams(Context, Params, std::nullopt);
838 }
839
840 if (!validateBoxingMethod(*this, Loc, NSArrayDecl, Sel, Method))
841 return ExprError();
842
843 // Dig out the type that all elements should be converted to.
844 QualType T = Method->parameters()[0]->getType();
845 const PointerType *PtrT = T->getAs<PointerType>();
846 if (!PtrT ||
848 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
849 << Sel;
850 Diag(Method->parameters()[0]->getLocation(),
851 diag::note_objc_literal_method_param)
852 << 0 << T
854 return ExprError();
855 }
856
857 // Check that the 'count' parameter is integral.
858 if (!Method->parameters()[1]->getType()->isIntegerType()) {
859 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
860 << Sel;
861 Diag(Method->parameters()[1]->getLocation(),
862 diag::note_objc_literal_method_param)
863 << 1
864 << Method->parameters()[1]->getType()
865 << "integral";
866 return ExprError();
867 }
868
869 // We've found a good +arrayWithObjects:count: method. Save it!
870 ArrayWithObjectsMethod = Method;
871 }
872
873 QualType ObjectsType = ArrayWithObjectsMethod->parameters()[0]->getType();
874 QualType RequiredType = ObjectsType->castAs<PointerType>()->getPointeeType();
875
876 // Check that each of the elements provided is valid in a collection literal,
877 // performing conversions as necessary.
878 Expr **ElementsBuffer = Elements.data();
879 for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
881 ElementsBuffer[I],
882 RequiredType, true);
883 if (Converted.isInvalid())
884 return ExprError();
885
886 ElementsBuffer[I] = Converted.get();
887 }
888
889 QualType Ty
892
894 ObjCArrayLiteral::Create(Context, Elements, Ty,
896}
897
898/// Check for duplicate keys in an ObjC dictionary literal. For instance:
899/// NSDictionary *nd = @{ @"foo" : @"bar", @"foo" : @"baz" };
900static void
902 ObjCDictionaryLiteral *Literal) {
903 if (Literal->isValueDependent() || Literal->isTypeDependent())
904 return;
905
906 // NSNumber has quite relaxed equality semantics (for instance, @YES is
907 // considered equal to @1.0). For now, ignore floating points and just do a
908 // bit-width and sign agnostic integer compare.
909 struct APSIntCompare {
910 bool operator()(const llvm::APSInt &LHS, const llvm::APSInt &RHS) const {
911 return llvm::APSInt::compareValues(LHS, RHS) < 0;
912 }
913 };
914
915 llvm::DenseMap<StringRef, SourceLocation> StringKeys;
916 std::map<llvm::APSInt, SourceLocation, APSIntCompare> IntegralKeys;
917
918 auto checkOneKey = [&](auto &Map, const auto &Key, SourceLocation Loc) {
919 auto Pair = Map.insert({Key, Loc});
920 if (!Pair.second) {
921 S.Diag(Loc, diag::warn_nsdictionary_duplicate_key);
922 S.Diag(Pair.first->second, diag::note_nsdictionary_duplicate_key_here);
923 }
924 };
925
926 for (unsigned Idx = 0, End = Literal->getNumElements(); Idx != End; ++Idx) {
927 Expr *Key = Literal->getKeyValueElement(Idx).Key->IgnoreParenImpCasts();
928
929 if (auto *StrLit = dyn_cast<ObjCStringLiteral>(Key)) {
930 StringRef Bytes = StrLit->getString()->getBytes();
931 SourceLocation Loc = StrLit->getExprLoc();
932 checkOneKey(StringKeys, Bytes, Loc);
933 }
934
935 if (auto *BE = dyn_cast<ObjCBoxedExpr>(Key)) {
936 Expr *Boxed = BE->getSubExpr();
937 SourceLocation Loc = BE->getExprLoc();
938
939 // Check for @("foo").
940 if (auto *Str = dyn_cast<StringLiteral>(Boxed->IgnoreParenImpCasts())) {
941 checkOneKey(StringKeys, Str->getBytes(), Loc);
942 continue;
943 }
944
946 if (Boxed->EvaluateAsInt(Result, S.getASTContext(),
948 checkOneKey(IntegralKeys, Result.Val.getInt(), Loc);
949 }
950 }
951 }
952}
953
956 SourceLocation Loc = SR.getBegin();
957
958 if (!NSDictionaryDecl) {
961 if (!NSDictionaryDecl) {
962 return ExprError();
963 }
964 }
965
966 // Find the dictionaryWithObjects:forKeys:count: method, if we haven't done
967 // so already.
970 Selector Sel = NSAPIObj->getNSDictionarySelector(
973 if (!Method && getLangOpts().DebuggerObjCLiteral) {
974 Method = ObjCMethodDecl::Create(
975 Context, SourceLocation(), SourceLocation(), Sel, IdT,
976 nullptr /*TypeSourceInfo */, Context.getTranslationUnitDecl(),
977 false /*Instance*/, false /*isVariadic*/,
978 /*isPropertyAccessor=*/false,
979 /*isSynthesizedAccessorStub=*/false,
980 /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
983 ParmVarDecl *objects = ParmVarDecl::Create(Context, Method,
986 &Context.Idents.get("objects"),
988 /*TInfo=*/nullptr, SC_None,
989 nullptr);
990 Params.push_back(objects);
994 &Context.Idents.get("keys"),
996 /*TInfo=*/nullptr, SC_None,
997 nullptr);
998 Params.push_back(keys);
1002 &Context.Idents.get("cnt"),
1004 /*TInfo=*/nullptr, SC_None,
1005 nullptr);
1006 Params.push_back(cnt);
1007 Method->setMethodParams(Context, Params, std::nullopt);
1008 }
1009
1010 if (!validateBoxingMethod(*this, SR.getBegin(), NSDictionaryDecl, Sel,
1011 Method))
1012 return ExprError();
1013
1014 // Dig out the type that all values should be converted to.
1015 QualType ValueT = Method->parameters()[0]->getType();
1016 const PointerType *PtrValue = ValueT->getAs<PointerType>();
1017 if (!PtrValue ||
1018 !Context.hasSameUnqualifiedType(PtrValue->getPointeeType(), IdT)) {
1019 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1020 << Sel;
1021 Diag(Method->parameters()[0]->getLocation(),
1022 diag::note_objc_literal_method_param)
1023 << 0 << ValueT
1025 return ExprError();
1026 }
1027
1028 // Dig out the type that all keys should be converted to.
1029 QualType KeyT = Method->parameters()[1]->getType();
1030 const PointerType *PtrKey = KeyT->getAs<PointerType>();
1031 if (!PtrKey ||
1033 IdT)) {
1034 bool err = true;
1035 if (PtrKey) {
1036 if (QIDNSCopying.isNull()) {
1037 // key argument of selector is id<NSCopying>?
1038 if (ObjCProtocolDecl *NSCopyingPDecl =
1039 LookupProtocol(&Context.Idents.get("NSCopying"), SR.getBegin())) {
1040 ObjCProtocolDecl *PQ[] = {NSCopyingPDecl};
1043 llvm::ArrayRef((ObjCProtocolDecl **)PQ, 1), false);
1045 }
1046 }
1047 if (!QIDNSCopying.isNull())
1049 QIDNSCopying);
1050 }
1051
1052 if (err) {
1053 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1054 << Sel;
1055 Diag(Method->parameters()[1]->getLocation(),
1056 diag::note_objc_literal_method_param)
1057 << 1 << KeyT
1059 return ExprError();
1060 }
1061 }
1062
1063 // Check that the 'count' parameter is integral.
1064 QualType CountType = Method->parameters()[2]->getType();
1065 if (!CountType->isIntegerType()) {
1066 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1067 << Sel;
1068 Diag(Method->parameters()[2]->getLocation(),
1069 diag::note_objc_literal_method_param)
1070 << 2 << CountType
1071 << "integral";
1072 return ExprError();
1073 }
1074
1075 // We've found a good +dictionaryWithObjects:keys:count: method; save it!
1077 }
1078
1079 QualType ValuesT = DictionaryWithObjectsMethod->parameters()[0]->getType();
1080 QualType ValueT = ValuesT->castAs<PointerType>()->getPointeeType();
1081 QualType KeysT = DictionaryWithObjectsMethod->parameters()[1]->getType();
1082 QualType KeyT = KeysT->castAs<PointerType>()->getPointeeType();
1083
1084 // Check that each of the keys and values provided is valid in a collection
1085 // literal, performing conversions as necessary.
1086 bool HasPackExpansions = false;
1087 for (ObjCDictionaryElement &Element : Elements) {
1088 // Check the key.
1089 ExprResult Key = CheckObjCCollectionLiteralElement(*this, Element.Key,
1090 KeyT);
1091 if (Key.isInvalid())
1092 return ExprError();
1093
1094 // Check the value.
1096 = CheckObjCCollectionLiteralElement(*this, Element.Value, ValueT);
1097 if (Value.isInvalid())
1098 return ExprError();
1099
1100 Element.Key = Key.get();
1101 Element.Value = Value.get();
1102
1103 if (Element.EllipsisLoc.isInvalid())
1104 continue;
1105
1106 if (!Element.Key->containsUnexpandedParameterPack() &&
1107 !Element.Value->containsUnexpandedParameterPack()) {
1108 Diag(Element.EllipsisLoc,
1109 diag::err_pack_expansion_without_parameter_packs)
1110 << SourceRange(Element.Key->getBeginLoc(),
1111 Element.Value->getEndLoc());
1112 return ExprError();
1113 }
1114
1115 HasPackExpansions = true;
1116 }
1117
1119 Context.getObjCInterfaceType(NSDictionaryDecl));
1120
1121 auto *Literal =
1122 ObjCDictionaryLiteral::Create(Context, Elements, HasPackExpansions, Ty,
1123 DictionaryWithObjectsMethod, SR);
1125 return MaybeBindToTemporary(Literal);
1126}
1127
1129 TypeSourceInfo *EncodedTypeInfo,
1130 SourceLocation RParenLoc) {
1131 QualType EncodedType = EncodedTypeInfo->getType();
1132 QualType StrTy;
1133 if (EncodedType->isDependentType())
1134 StrTy = Context.DependentTy;
1135 else {
1136 if (!EncodedType->getAsArrayTypeUnsafe() && //// Incomplete array is handled.
1137 !EncodedType->isVoidType()) // void is handled too.
1138 if (RequireCompleteType(AtLoc, EncodedType,
1139 diag::err_incomplete_type_objc_at_encode,
1140 EncodedTypeInfo->getTypeLoc()))
1141 return ExprError();
1142
1143 std::string Str;
1144 QualType NotEncodedT;
1145 Context.getObjCEncodingForType(EncodedType, Str, nullptr, &NotEncodedT);
1146 if (!NotEncodedT.isNull())
1147 Diag(AtLoc, diag::warn_incomplete_encoded_type)
1148 << EncodedType << NotEncodedT;
1149
1150 // The type of @encode is the same as the type of the corresponding string,
1151 // which is an array type.
1152 StrTy = Context.getStringLiteralArrayType(Context.CharTy, Str.size());
1153 }
1154
1155 return new (Context) ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc);
1156}
1157
1159 SourceLocation EncodeLoc,
1160 SourceLocation LParenLoc,
1161 ParsedType ty,
1162 SourceLocation RParenLoc) {
1163 // FIXME: Preserve type source info ?
1164 TypeSourceInfo *TInfo;
1165 QualType EncodedType = GetTypeFromParser(ty, &TInfo);
1166 if (!TInfo)
1167 TInfo = Context.getTrivialTypeSourceInfo(EncodedType,
1168 getLocForEndOfToken(LParenLoc));
1169
1170 return BuildObjCEncodeExpression(AtLoc, TInfo, RParenLoc);
1171}
1172
1174 SourceLocation AtLoc,
1175 SourceLocation LParenLoc,
1176 SourceLocation RParenLoc,
1177 ObjCMethodDecl *Method,
1178 ObjCMethodList &MethList) {
1179 ObjCMethodList *M = &MethList;
1180 bool Warned = false;
1181 for (M = M->getNext(); M; M=M->getNext()) {
1182 ObjCMethodDecl *MatchingMethodDecl = M->getMethod();
1183 if (MatchingMethodDecl == Method ||
1184 isa<ObjCImplDecl>(MatchingMethodDecl->getDeclContext()) ||
1185 MatchingMethodDecl->getSelector() != Method->getSelector())
1186 continue;
1187 if (!S.MatchTwoMethodDeclarations(Method,
1188 MatchingMethodDecl, Sema::MMS_loose)) {
1189 if (!Warned) {
1190 Warned = true;
1191 S.Diag(AtLoc, diag::warn_multiple_selectors)
1192 << Method->getSelector() << FixItHint::CreateInsertion(LParenLoc, "(")
1193 << FixItHint::CreateInsertion(RParenLoc, ")");
1194 S.Diag(Method->getLocation(), diag::note_method_declared_at)
1195 << Method->getDeclName();
1196 }
1197 S.Diag(MatchingMethodDecl->getLocation(), diag::note_method_declared_at)
1198 << MatchingMethodDecl->getDeclName();
1199 }
1200 }
1201 return Warned;
1202}
1203
1205 ObjCMethodDecl *Method,
1206 SourceLocation LParenLoc,
1207 SourceLocation RParenLoc,
1208 bool WarnMultipleSelectors) {
1209 if (!WarnMultipleSelectors ||
1210 S.Diags.isIgnored(diag::warn_multiple_selectors, SourceLocation()))
1211 return;
1212 bool Warned = false;
1214 e = S.MethodPool.end(); b != e; b++) {
1215 // first, instance methods
1216 ObjCMethodList &InstMethList = b->second.first;
1217 if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,
1218 Method, InstMethList))
1219 Warned = true;
1220
1221 // second, class methods
1222 ObjCMethodList &ClsMethList = b->second.second;
1223 if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,
1224 Method, ClsMethList) || Warned)
1225 return;
1226 }
1227}
1228
1230 ObjCMethodList &MethList,
1231 bool &onlyDirect,
1232 bool &anyDirect) {
1233 (void)Sel;
1234 ObjCMethodList *M = &MethList;
1235 ObjCMethodDecl *DirectMethod = nullptr;
1236 for (; M; M = M->getNext()) {
1237 ObjCMethodDecl *Method = M->getMethod();
1238 if (!Method)
1239 continue;
1240 assert(Method->getSelector() == Sel && "Method with wrong selector in method list");
1241 if (Method->isDirectMethod()) {
1242 anyDirect = true;
1243 DirectMethod = Method;
1244 } else
1245 onlyDirect = false;
1246 }
1247
1248 return DirectMethod;
1249}
1250
1251// Search the global pool for (potentially) direct methods matching the given
1252// selector. If a non-direct method is found, set \param onlyDirect to false. If
1253// a direct method is found, set \param anyDirect to true. Returns a direct
1254// method, if any.
1256 bool &onlyDirect,
1257 bool &anyDirect) {
1258 auto Iter = S.MethodPool.find(Sel);
1259 if (Iter == S.MethodPool.end())
1260 return nullptr;
1261
1263 S, Sel, Iter->second.first, onlyDirect, anyDirect);
1265 S, Sel, Iter->second.second, onlyDirect, anyDirect);
1266
1267 return DirectInstance ? DirectInstance : DirectClass;
1268}
1269
1271 auto *CurMD = S.getCurMethodDecl();
1272 if (!CurMD)
1273 return nullptr;
1274 ObjCInterfaceDecl *IFace = CurMD->getClassInterface();
1275
1276 // The language enforce that only one direct method is present in a given
1277 // class, so we just need to find one method in the current class to know
1278 // whether Sel is potentially direct in this context.
1279 if (ObjCMethodDecl *MD = IFace->lookupMethod(Sel, /*isInstance=*/true))
1280 return MD;
1281 if (ObjCMethodDecl *MD = IFace->lookupPrivateMethod(Sel, /*Instance=*/true))
1282 return MD;
1283 if (ObjCMethodDecl *MD = IFace->lookupMethod(Sel, /*isInstance=*/false))
1284 return MD;
1285 if (ObjCMethodDecl *MD = IFace->lookupPrivateMethod(Sel, /*Instance=*/false))
1286 return MD;
1287
1288 return nullptr;
1289}
1290
1292 SourceLocation AtLoc,
1293 SourceLocation SelLoc,
1294 SourceLocation LParenLoc,
1295 SourceLocation RParenLoc,
1296 bool WarnMultipleSelectors) {
1298 SourceRange(LParenLoc, RParenLoc));
1299 if (!Method)
1301 SourceRange(LParenLoc, RParenLoc));
1302 if (!Method) {
1303 if (const ObjCMethodDecl *OM = SelectorsForTypoCorrection(Sel)) {
1304 Selector MatchedSel = OM->getSelector();
1305 SourceRange SelectorRange(LParenLoc.getLocWithOffset(1),
1306 RParenLoc.getLocWithOffset(-1));
1307 Diag(SelLoc, diag::warn_undeclared_selector_with_typo)
1308 << Sel << MatchedSel
1309 << FixItHint::CreateReplacement(SelectorRange, MatchedSel.getAsString());
1310
1311 } else
1312 Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
1313 } else {
1314 DiagnoseMismatchedSelectors(*this, AtLoc, Method, LParenLoc, RParenLoc,
1315 WarnMultipleSelectors);
1316
1317 bool onlyDirect = true;
1318 bool anyDirect = false;
1319 ObjCMethodDecl *GlobalDirectMethod =
1320 LookupDirectMethodInGlobalPool(*this, Sel, onlyDirect, anyDirect);
1321
1322 if (onlyDirect) {
1323 Diag(AtLoc, diag::err_direct_selector_expression)
1324 << Method->getSelector();
1325 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
1326 << Method->getDeclName();
1327 } else if (anyDirect) {
1328 // If we saw any direct methods, see if we see a direct member of the
1329 // current class. If so, the @selector will likely be used to refer to
1330 // this direct method.
1331 ObjCMethodDecl *LikelyTargetMethod = findMethodInCurrentClass(*this, Sel);
1332 if (LikelyTargetMethod && LikelyTargetMethod->isDirectMethod()) {
1333 Diag(AtLoc, diag::warn_potentially_direct_selector_expression) << Sel;
1334 Diag(LikelyTargetMethod->getLocation(),
1335 diag::note_direct_method_declared_at)
1336 << LikelyTargetMethod->getDeclName();
1337 } else if (!LikelyTargetMethod) {
1338 // Otherwise, emit the "strict" variant of this diagnostic, unless
1339 // LikelyTargetMethod is non-direct.
1340 Diag(AtLoc, diag::warn_strict_potentially_direct_selector_expression)
1341 << Sel;
1342 Diag(GlobalDirectMethod->getLocation(),
1343 diag::note_direct_method_declared_at)
1344 << GlobalDirectMethod->getDeclName();
1345 }
1346 }
1347 }
1348
1349 if (Method &&
1350 Method->getImplementationControl() !=
1352 !getSourceManager().isInSystemHeader(Method->getLocation()))
1353 ReferencedSelectors.insert(std::make_pair(Sel, AtLoc));
1354
1355 // In ARC, forbid the user from using @selector for
1356 // retain/release/autorelease/dealloc/retainCount.
1357 if (getLangOpts().ObjCAutoRefCount) {
1358 switch (Sel.getMethodFamily()) {
1359 case OMF_retain:
1360 case OMF_release:
1361 case OMF_autorelease:
1362 case OMF_retainCount:
1363 case OMF_dealloc:
1364 Diag(AtLoc, diag::err_arc_illegal_selector) <<
1365 Sel << SourceRange(LParenLoc, RParenLoc);
1366 break;
1367
1368 case OMF_None:
1369 case OMF_alloc:
1370 case OMF_copy:
1371 case OMF_finalize:
1372 case OMF_init:
1373 case OMF_mutableCopy:
1374 case OMF_new:
1375 case OMF_self:
1376 case OMF_initialize:
1378 break;
1379 }
1380 }
1382 return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);
1383}
1384
1386 SourceLocation AtLoc,
1387 SourceLocation ProtoLoc,
1388 SourceLocation LParenLoc,
1389 SourceLocation ProtoIdLoc,
1390 SourceLocation RParenLoc) {
1391 ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId, ProtoIdLoc);
1392 if (!PDecl) {
1393 Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
1394 return true;
1395 }
1396 if (PDecl->isNonRuntimeProtocol())
1397 Diag(ProtoLoc, diag::err_objc_non_runtime_protocol_in_protocol_expr)
1398 << PDecl;
1399 if (!PDecl->hasDefinition()) {
1400 Diag(ProtoLoc, diag::err_atprotocol_protocol) << PDecl;
1401 Diag(PDecl->getLocation(), diag::note_entity_declared_at) << PDecl;
1402 } else {
1403 PDecl = PDecl->getDefinition();
1404 }
1405
1407 if (Ty.isNull())
1408 return true;
1410 return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, ProtoIdLoc, RParenLoc);
1411}
1412
1413/// Try to capture an implicit reference to 'self'.
1416
1417 // If we're not in an ObjC method, error out. Note that, unlike the
1418 // C++ case, we don't require an instance method --- class methods
1419 // still have a 'self', and we really do still need to capture it!
1420 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(DC);
1421 if (!method)
1422 return nullptr;
1423
1424 tryCaptureVariable(method->getSelfDecl(), Loc);
1425
1426 return method;
1427}
1428
1430 QualType origType = T;
1431 if (auto nullability = AttributedType::stripOuterNullability(T)) {
1432 if (T == Context.getObjCInstanceType()) {
1433 return Context.getAttributedType(
1435 Context.getObjCIdType(),
1436 Context.getObjCIdType());
1437 }
1438
1439 return origType;
1440 }
1441
1442 if (T == Context.getObjCInstanceType())
1443 return Context.getObjCIdType();
1444
1445 return origType;
1446}
1447
1448/// Determine the result type of a message send based on the receiver type,
1449/// method, and the kind of message send.
1450///
1451/// This is the "base" result type, which will still need to be adjusted
1452/// to account for nullability.
1454 QualType ReceiverType,
1455 ObjCMethodDecl *Method,
1456 bool isClassMessage,
1457 bool isSuperMessage) {
1458 assert(Method && "Must have a method");
1459 if (!Method->hasRelatedResultType())
1460 return Method->getSendResultType(ReceiverType);
1461
1462 ASTContext &Context = S.Context;
1463
1464 // Local function that transfers the nullability of the method's
1465 // result type to the returned result.
1466 auto transferNullability = [&](QualType type) -> QualType {
1467 // If the method's result type has nullability, extract it.
1468 if (auto nullability =
1469 Method->getSendResultType(ReceiverType)->getNullability()) {
1470 // Strip off any outer nullability sugar from the provided type.
1472
1473 // Form a new attributed type using the method result type's nullability.
1474 return Context.getAttributedType(
1476 type,
1477 type);
1478 }
1479
1480 return type;
1481 };
1482
1483 // If a method has a related return type:
1484 // - if the method found is an instance method, but the message send
1485 // was a class message send, T is the declared return type of the method
1486 // found
1487 if (Method->isInstanceMethod() && isClassMessage)
1488 return stripObjCInstanceType(Context,
1489 Method->getSendResultType(ReceiverType));
1490
1491 // - if the receiver is super, T is a pointer to the class of the
1492 // enclosing method definition
1493 if (isSuperMessage) {
1494 if (ObjCMethodDecl *CurMethod = S.getCurMethodDecl())
1495 if (ObjCInterfaceDecl *Class = CurMethod->getClassInterface()) {
1496 return transferNullability(
1498 Context.getObjCInterfaceType(Class)));
1499 }
1500 }
1501
1502 // - if the receiver is the name of a class U, T is a pointer to U
1503 if (ReceiverType->getAsObjCInterfaceType())
1504 return transferNullability(Context.getObjCObjectPointerType(ReceiverType));
1505 // - if the receiver is of type Class or qualified Class type,
1506 // T is the declared return type of the method.
1507 if (ReceiverType->isObjCClassType() ||
1508 ReceiverType->isObjCQualifiedClassType())
1509 return stripObjCInstanceType(Context,
1510 Method->getSendResultType(ReceiverType));
1511
1512 // - if the receiver is id, qualified id, Class, or qualified Class, T
1513 // is the receiver type, otherwise
1514 // - T is the type of the receiver expression.
1515 return transferNullability(ReceiverType);
1516}
1517
1519 QualType ReceiverType,
1520 ObjCMethodDecl *Method,
1521 bool isClassMessage,
1522 bool isSuperMessage) {
1523 // Produce the result type.
1524 QualType resultType = getBaseMessageSendResultType(*this, ReceiverType,
1525 Method,
1526 isClassMessage,
1527 isSuperMessage);
1528
1529 // If this is a class message, ignore the nullability of the receiver.
1530 if (isClassMessage) {
1531 // In a class method, class messages to 'self' that return instancetype can
1532 // be typed as the current class. We can safely do this in ARC because self
1533 // can't be reassigned, and we do it unsafely outside of ARC because in
1534 // practice people never reassign self in class methods and there's some
1535 // virtue in not being aggressively pedantic.
1536 if (Receiver && Receiver->isObjCSelfExpr()) {
1537 assert(ReceiverType->isObjCClassType() && "expected a Class self");
1538 QualType T = Method->getSendResultType(ReceiverType);
1540 if (T == Context.getObjCInstanceType()) {
1541 const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(
1542 cast<ImplicitParamDecl>(
1543 cast<DeclRefExpr>(Receiver->IgnoreParenImpCasts())->getDecl())
1544 ->getDeclContext());
1545 assert(MD->isClassMethod() && "expected a class method");
1548 if (auto Nullability = resultType->getNullability())
1549 NewResultType = Context.getAttributedType(
1551 NewResultType, NewResultType);
1552 return NewResultType;
1553 }
1554 }
1555 return resultType;
1556 }
1557
1558 // There is nothing left to do if the result type cannot have a nullability
1559 // specifier.
1560 if (!resultType->canHaveNullability())
1561 return resultType;
1562
1563 // Map the nullability of the result into a table index.
1564 unsigned receiverNullabilityIdx = 0;
1565 if (std::optional<NullabilityKind> nullability =
1566 ReceiverType->getNullability()) {
1567 if (*nullability == NullabilityKind::NullableResult)
1568 nullability = NullabilityKind::Nullable;
1569 receiverNullabilityIdx = 1 + static_cast<unsigned>(*nullability);
1570 }
1571
1572 unsigned resultNullabilityIdx = 0;
1573 if (std::optional<NullabilityKind> nullability =
1574 resultType->getNullability()) {
1575 if (*nullability == NullabilityKind::NullableResult)
1576 nullability = NullabilityKind::Nullable;
1577 resultNullabilityIdx = 1 + static_cast<unsigned>(*nullability);
1578 }
1579
1580 // The table of nullability mappings, indexed by the receiver's nullability
1581 // and then the result type's nullability.
1582 static const uint8_t None = 0;
1583 static const uint8_t NonNull = 1;
1584 static const uint8_t Nullable = 2;
1585 static const uint8_t Unspecified = 3;
1586 static const uint8_t nullabilityMap[4][4] = {
1587 // None NonNull Nullable Unspecified
1588 /* None */ { None, None, Nullable, None },
1589 /* NonNull */ { None, NonNull, Nullable, Unspecified },
1590 /* Nullable */ { Nullable, Nullable, Nullable, Nullable },
1591 /* Unspecified */ { None, Unspecified, Nullable, Unspecified }
1592 };
1593
1594 unsigned newResultNullabilityIdx
1595 = nullabilityMap[receiverNullabilityIdx][resultNullabilityIdx];
1596 if (newResultNullabilityIdx == resultNullabilityIdx)
1597 return resultType;
1598
1599 // Strip off the existing nullability. This removes as little type sugar as
1600 // possible.
1601 do {
1602 if (auto attributed = dyn_cast<AttributedType>(resultType.getTypePtr())) {
1603 resultType = attributed->getModifiedType();
1604 } else {
1605 resultType = resultType.getDesugaredType(Context);
1606 }
1607 } while (resultType->getNullability());
1608
1609 // Add nullability back if needed.
1610 if (newResultNullabilityIdx > 0) {
1611 auto newNullability
1612 = static_cast<NullabilityKind>(newResultNullabilityIdx-1);
1615 resultType, resultType);
1616 }
1617
1618 return resultType;
1619}
1620
1621/// Look for an ObjC method whose result type exactly matches the given type.
1622static const ObjCMethodDecl *
1624 QualType instancetype) {
1625 if (MD->getReturnType() == instancetype)
1626 return MD;
1627
1628 // For these purposes, a method in an @implementation overrides a
1629 // declaration in the @interface.
1630 if (const ObjCImplDecl *impl =
1631 dyn_cast<ObjCImplDecl>(MD->getDeclContext())) {
1632 const ObjCContainerDecl *iface;
1633 if (const ObjCCategoryImplDecl *catImpl =
1634 dyn_cast<ObjCCategoryImplDecl>(impl)) {
1635 iface = catImpl->getCategoryDecl();
1636 } else {
1637 iface = impl->getClassInterface();
1638 }
1639
1640 const ObjCMethodDecl *ifaceMD =
1641 iface->getMethod(MD->getSelector(), MD->isInstanceMethod());
1642 if (ifaceMD) return findExplicitInstancetypeDeclarer(ifaceMD, instancetype);
1643 }
1644
1646 MD->getOverriddenMethods(overrides);
1647 for (unsigned i = 0, e = overrides.size(); i != e; ++i) {
1648 if (const ObjCMethodDecl *result =
1649 findExplicitInstancetypeDeclarer(overrides[i], instancetype))
1650 return result;
1651 }
1652
1653 return nullptr;
1654}
1655
1657 // Only complain if we're in an ObjC method and the required return
1658 // type doesn't match the method's declared return type.
1659 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CurContext);
1660 if (!MD || !MD->hasRelatedResultType() ||
1662 return;
1663
1664 // Look for a method overridden by this method which explicitly uses
1665 // 'instancetype'.
1666 if (const ObjCMethodDecl *overridden =
1668 SourceRange range = overridden->getReturnTypeSourceRange();
1669 SourceLocation loc = range.getBegin();
1670 if (loc.isInvalid())
1671 loc = overridden->getLocation();
1672 Diag(loc, diag::note_related_result_type_explicit)
1673 << /*current method*/ 1 << range;
1674 return;
1675 }
1676
1677 // Otherwise, if we have an interesting method family, note that.
1678 // This should always trigger if the above didn't.
1679 if (ObjCMethodFamily family = MD->getMethodFamily())
1680 Diag(MD->getLocation(), diag::note_related_result_type_family)
1681 << /*current method*/ 1
1682 << family;
1683}
1684
1686 E = E->IgnoreParenImpCasts();
1687 const ObjCMessageExpr *MsgSend = dyn_cast<ObjCMessageExpr>(E);
1688 if (!MsgSend)
1689 return;
1690
1691 const ObjCMethodDecl *Method = MsgSend->getMethodDecl();
1692 if (!Method)
1693 return;
1694
1695 if (!Method->hasRelatedResultType())
1696 return;
1697
1699 Method->getReturnType().getNonReferenceType(), MsgSend->getType()))
1700 return;
1701
1704 return;
1705
1706 Diag(Method->getLocation(), diag::note_related_result_type_inferred)
1707 << Method->isInstanceMethod() << Method->getSelector()
1708 << MsgSend->getType();
1709}
1710
1712 const Expr *Receiver, QualType ReceiverType, MultiExprArg Args,
1713 Selector Sel, ArrayRef<SourceLocation> SelectorLocs, ObjCMethodDecl *Method,
1714 bool isClassMessage, bool isSuperMessage, SourceLocation lbrac,
1715 SourceLocation rbrac, SourceRange RecRange, QualType &ReturnType,
1716 ExprValueKind &VK) {
1717 SourceLocation SelLoc;
1718 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
1719 SelLoc = SelectorLocs.front();
1720 else
1721 SelLoc = lbrac;
1722
1723 if (!Method) {
1724 // Apply default argument promotion as for (C99 6.5.2.2p6).
1725 for (unsigned i = 0, e = Args.size(); i != e; i++) {
1726 if (Args[i]->isTypeDependent())
1727 continue;
1728
1729 ExprResult result;
1730 if (getLangOpts().DebuggerSupport) {
1731 QualType paramTy; // ignored
1732 result = checkUnknownAnyArg(SelLoc, Args[i], paramTy);
1733 } else {
1734 result = DefaultArgumentPromotion(Args[i]);
1735 }
1736 if (result.isInvalid())
1737 return true;
1738 Args[i] = result.get();
1739 }
1740
1741 unsigned DiagID;
1742 if (getLangOpts().ObjCAutoRefCount)
1743 DiagID = diag::err_arc_method_not_found;
1744 else
1745 DiagID = isClassMessage ? diag::warn_class_method_not_found
1746 : diag::warn_inst_method_not_found;
1747 if (!getLangOpts().DebuggerSupport) {
1748 const ObjCMethodDecl *OMD = SelectorsForTypoCorrection(Sel, ReceiverType);
1749 if (OMD && !OMD->isInvalidDecl()) {
1750 if (getLangOpts().ObjCAutoRefCount)
1751 DiagID = diag::err_method_not_found_with_typo;
1752 else
1753 DiagID = isClassMessage ? diag::warn_class_method_not_found_with_typo
1754 : diag::warn_instance_method_not_found_with_typo;
1755 Selector MatchedSel = OMD->getSelector();
1756 SourceRange SelectorRange(SelectorLocs.front(), SelectorLocs.back());
1757 if (MatchedSel.isUnarySelector())
1758 Diag(SelLoc, DiagID)
1759 << Sel<< isClassMessage << MatchedSel
1760 << FixItHint::CreateReplacement(SelectorRange, MatchedSel.getAsString());
1761 else
1762 Diag(SelLoc, DiagID) << Sel<< isClassMessage << MatchedSel;
1763 }
1764 else
1765 Diag(SelLoc, DiagID)
1766 << Sel << isClassMessage << SourceRange(SelectorLocs.front(),
1767 SelectorLocs.back());
1768 // Find the class to which we are sending this message.
1769 if (auto *ObjPT = ReceiverType->getAs<ObjCObjectPointerType>()) {
1770 if (ObjCInterfaceDecl *ThisClass = ObjPT->getInterfaceDecl()) {
1771 Diag(ThisClass->getLocation(), diag::note_receiver_class_declared);
1772 if (!RecRange.isInvalid())
1773 if (ThisClass->lookupClassMethod(Sel))
1774 Diag(RecRange.getBegin(), diag::note_receiver_expr_here)
1775 << FixItHint::CreateReplacement(RecRange,
1776 ThisClass->getNameAsString());
1777 }
1778 }
1779 }
1780
1781 // In debuggers, we want to use __unknown_anytype for these
1782 // results so that clients can cast them.
1783 if (getLangOpts().DebuggerSupport) {
1784 ReturnType = Context.UnknownAnyTy;
1785 } else {
1786 ReturnType = Context.getObjCIdType();
1787 }
1788 VK = VK_PRValue;
1789 return false;
1790 }
1791
1792 ReturnType = getMessageSendResultType(Receiver, ReceiverType, Method,
1793 isClassMessage, isSuperMessage);
1795
1796 unsigned NumNamedArgs = Sel.getNumArgs();
1797 // Method might have more arguments than selector indicates. This is due
1798 // to addition of c-style arguments in method.
1799 if (Method->param_size() > Sel.getNumArgs())
1800 NumNamedArgs = Method->param_size();
1801 // FIXME. This need be cleaned up.
1802 if (Args.size() < NumNamedArgs) {
1803 Diag(SelLoc, diag::err_typecheck_call_too_few_args)
1804 << 2 << NumNamedArgs << static_cast<unsigned>(Args.size())
1805 << /*is non object*/ 0;
1806 return false;
1807 }
1808
1809 // Compute the set of type arguments to be substituted into each parameter
1810 // type.
1811 std::optional<ArrayRef<QualType>> typeArgs =
1812 ReceiverType->getObjCSubstitutions(Method->getDeclContext());
1813 bool IsError = false;
1814 for (unsigned i = 0; i < NumNamedArgs; i++) {
1815 // We can't do any type-checking on a type-dependent argument.
1816 if (Args[i]->isTypeDependent())
1817 continue;
1818
1819 Expr *argExpr = Args[i];
1820
1821 ParmVarDecl *param = Method->parameters()[i];
1822 assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
1823
1824 if (param->hasAttr<NoEscapeAttr>() &&
1825 param->getType()->isBlockPointerType())
1826 if (auto *BE = dyn_cast<BlockExpr>(
1827 argExpr->IgnoreParenNoopCasts(Context)))
1828 BE->getBlockDecl()->setDoesNotEscape();
1829
1830 // Strip the unbridged-cast placeholder expression off unless it's
1831 // a consumed argument.
1832 if (argExpr->hasPlaceholderType(BuiltinType::ARCUnbridgedCast) &&
1833 !param->hasAttr<CFConsumedAttr>())
1834 argExpr = stripARCUnbridgedCast(argExpr);
1835
1836 // If the parameter is __unknown_anytype, infer its type
1837 // from the argument.
1838 if (param->getType() == Context.UnknownAnyTy) {
1839 QualType paramType;
1840 ExprResult argE = checkUnknownAnyArg(SelLoc, argExpr, paramType);
1841 if (argE.isInvalid()) {
1842 IsError = true;
1843 } else {
1844 Args[i] = argE.get();
1845
1846 // Update the parameter type in-place.
1847 param->setType(paramType);
1848 }
1849 continue;
1850 }
1851
1852 QualType origParamType = param->getType();
1853 QualType paramType = param->getType();
1854 if (typeArgs)
1855 paramType = paramType.substObjCTypeArgs(
1856 Context,
1857 *typeArgs,
1859
1861 paramType,
1862 diag::err_call_incomplete_argument, argExpr))
1863 return true;
1864
1865 InitializedEntity Entity
1867 ExprResult ArgE = PerformCopyInitialization(Entity, SourceLocation(), argExpr);
1868 if (ArgE.isInvalid())
1869 IsError = true;
1870 else {
1871 Args[i] = ArgE.getAs<Expr>();
1872
1873 // If we are type-erasing a block to a block-compatible
1874 // Objective-C pointer type, we may need to extend the lifetime
1875 // of the block object.
1876 if (typeArgs && Args[i]->isPRValue() && paramType->isBlockPointerType() &&
1877 Args[i]->getType()->isBlockPointerType() &&
1878 origParamType->isObjCObjectPointerType()) {
1879 ExprResult arg = Args[i];
1881 Args[i] = arg.get();
1882 }
1883 }
1884 }
1885
1886 // Promote additional arguments to variadic methods.
1887 if (Method->isVariadic()) {
1888 for (unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) {
1889 if (Args[i]->isTypeDependent())
1890 continue;
1891
1893 nullptr);
1894 IsError |= Arg.isInvalid();
1895 Args[i] = Arg.get();
1896 }
1897 } else {
1898 // Check for extra arguments to non-variadic methods.
1899 if (Args.size() != NumNamedArgs) {
1900 Diag(Args[NumNamedArgs]->getBeginLoc(),
1901 diag::err_typecheck_call_too_many_args)
1902 << 2 /*method*/ << NumNamedArgs << static_cast<unsigned>(Args.size())
1903 << Method->getSourceRange() << /*is non object*/ 0
1904 << SourceRange(Args[NumNamedArgs]->getBeginLoc(),
1905 Args.back()->getEndLoc());
1906 }
1907 }
1908
1909 DiagnoseSentinelCalls(Method, SelLoc, Args);
1910
1911 // Do additional checkings on method.
1912 IsError |=
1913 CheckObjCMethodCall(Method, SelLoc, ArrayRef(Args.data(), Args.size()));
1914
1915 return IsError;
1916}
1917
1919 // 'self' is objc 'self' in an objc method only.
1920 ObjCMethodDecl *Method =
1921 dyn_cast_or_null<ObjCMethodDecl>(CurContext->getNonClosureAncestor());
1922 return isSelfExpr(RExpr, Method);
1923}
1924
1925bool Sema::isSelfExpr(Expr *receiver, const ObjCMethodDecl *method) {
1926 if (!method) return false;
1927
1928 receiver = receiver->IgnoreParenLValueCasts();
1929 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(receiver))
1930 if (DRE->getDecl() == method->getSelfDecl())
1931 return true;
1932 return false;
1933}
1934
1935/// LookupMethodInType - Look up a method in an ObjCObjectType.
1937 bool isInstance) {
1938 const ObjCObjectType *objType = type->castAs<ObjCObjectType>();
1939 if (ObjCInterfaceDecl *iface = objType->getInterface()) {
1940 // Look it up in the main interface (and categories, etc.)
1941 if (ObjCMethodDecl *method = iface->lookupMethod(sel, isInstance))
1942 return method;
1943
1944 // Okay, look for "private" methods declared in any
1945 // @implementations we've seen.
1946 if (ObjCMethodDecl *method = iface->lookupPrivateMethod(sel, isInstance))
1947 return method;
1948 }
1949
1950 // Check qualifiers.
1951 for (const auto *I : objType->quals())
1952 if (ObjCMethodDecl *method = I->lookupMethod(sel, isInstance))
1953 return method;
1954
1955 return nullptr;
1956}
1957
1958/// LookupMethodInQualifiedType - Lookups up a method in protocol qualifier
1959/// list of a qualified objective pointer type.
1961 const ObjCObjectPointerType *OPT,
1962 bool Instance)
1963{
1964 ObjCMethodDecl *MD = nullptr;
1965 for (const auto *PROTO : OPT->quals()) {
1966 if ((MD = PROTO->lookupMethod(Sel, Instance))) {
1967 return MD;
1968 }
1969 }
1970 return nullptr;
1971}
1972
1973/// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an
1974/// objective C interface. This is a property reference expression.
1977 Expr *BaseExpr, SourceLocation OpLoc,
1978 DeclarationName MemberName,
1979 SourceLocation MemberLoc,
1980 SourceLocation SuperLoc, QualType SuperType,
1981 bool Super) {
1982 const ObjCInterfaceType *IFaceT = OPT->getInterfaceType();
1983 ObjCInterfaceDecl *IFace = IFaceT->getDecl();
1984
1985 if (!MemberName.isIdentifier()) {
1986 Diag(MemberLoc, diag::err_invalid_property_name)
1987 << MemberName << QualType(OPT, 0);
1988 return ExprError();
1989 }
1990
1992
1993 SourceRange BaseRange = Super? SourceRange(SuperLoc)
1994 : BaseExpr->getSourceRange();
1995 if (RequireCompleteType(MemberLoc, OPT->getPointeeType(),
1996 diag::err_property_not_found_forward_class,
1997 MemberName, BaseRange))
1998 return ExprError();
1999
2002 // Check whether we can reference this property.
2003 if (DiagnoseUseOfDecl(PD, MemberLoc))
2004 return ExprError();
2005 if (Super)
2006 return new (Context)
2008 OK_ObjCProperty, MemberLoc, SuperLoc, SuperType);
2009 else
2010 return new (Context)
2012 OK_ObjCProperty, MemberLoc, BaseExpr);
2013 }
2014 // Check protocols on qualified interfaces.
2015 for (const auto *I : OPT->quals())
2016 if (ObjCPropertyDecl *PD = I->FindPropertyDeclaration(
2018 // Check whether we can reference this property.
2019 if (DiagnoseUseOfDecl(PD, MemberLoc))
2020 return ExprError();
2021
2022 if (Super)
2023 return new (Context) ObjCPropertyRefExpr(
2025 SuperLoc, SuperType);
2026 else
2027 return new (Context)
2029 OK_ObjCProperty, MemberLoc, BaseExpr);
2030 }
2031 // If that failed, look for an "implicit" property by seeing if the nullary
2032 // selector is implemented.
2033
2034 // FIXME: The logic for looking up nullary and unary selectors should be
2035 // shared with the code in ActOnInstanceMessage.
2036
2038 ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
2039
2040 // May be found in property's qualified list.
2041 if (!Getter)
2042 Getter = LookupMethodInQualifiedType(Sel, OPT, true);
2043
2044 // If this reference is in an @implementation, check for 'private' methods.
2045 if (!Getter)
2046 Getter = IFace->lookupPrivateMethod(Sel);
2047
2048 if (Getter) {
2049 // Check if we can reference this property.
2050 if (DiagnoseUseOfDecl(Getter, MemberLoc))
2051 return ExprError();
2052 }
2053 // If we found a getter then this may be a valid dot-reference, we
2054 // will look for the matching setter, in case it is needed.
2055 Selector SetterSel =
2058 ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
2059
2060 // May be found in property's qualified list.
2061 if (!Setter)
2062 Setter = LookupMethodInQualifiedType(SetterSel, OPT, true);
2063
2064 if (!Setter) {
2065 // If this reference is in an @implementation, also check for 'private'
2066 // methods.
2067 Setter = IFace->lookupPrivateMethod(SetterSel);
2068 }
2069
2070 if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
2071 return ExprError();
2072
2073 // Special warning if member name used in a property-dot for a setter accessor
2074 // does not use a property with same name; e.g. obj.X = ... for a property with
2075 // name 'x'.
2076 if (Setter && Setter->isImplicit() && Setter->isPropertyAccessor() &&
2079 if (const ObjCPropertyDecl *PDecl = Setter->findPropertyDecl()) {
2080 // Do not warn if user is using property-dot syntax to make call to
2081 // user named setter.
2082 if (!(PDecl->getPropertyAttributes() &
2084 Diag(MemberLoc,
2085 diag::warn_property_access_suggest)
2086 << MemberName << QualType(OPT, 0) << PDecl->getName()
2087 << FixItHint::CreateReplacement(MemberLoc, PDecl->getName());
2088 }
2089 }
2090
2091 if (Getter || Setter) {
2092 if (Super)
2093 return new (Context)
2095 OK_ObjCProperty, MemberLoc, SuperLoc, SuperType);
2096 else
2097 return new (Context)
2099 OK_ObjCProperty, MemberLoc, BaseExpr);
2100
2101 }
2102
2103 // Attempt to correct for typos in property names.
2105 if (TypoCorrection Corrected = CorrectTypo(
2106 DeclarationNameInfo(MemberName, MemberLoc), LookupOrdinaryName,
2107 nullptr, nullptr, CCC, CTK_ErrorRecovery, IFace, false, OPT)) {
2108 DeclarationName TypoResult = Corrected.getCorrection();
2109 if (TypoResult.isIdentifier() &&
2110 TypoResult.getAsIdentifierInfo() == Member) {
2111 // There is no need to try the correction if it is the same.
2112 NamedDecl *ChosenDecl =
2113 Corrected.isKeyword() ? nullptr : Corrected.getFoundDecl();
2114 if (ChosenDecl && isa<ObjCPropertyDecl>(ChosenDecl))
2115 if (cast<ObjCPropertyDecl>(ChosenDecl)->isClassProperty()) {
2116 // This is a class property, we should not use the instance to
2117 // access it.
2118 Diag(MemberLoc, diag::err_class_property_found) << MemberName
2119 << OPT->getInterfaceDecl()->getName()
2121 OPT->getInterfaceDecl()->getName());
2122 return ExprError();
2123 }
2124 } else {
2125 diagnoseTypo(Corrected, PDiag(diag::err_property_not_found_suggest)
2126 << MemberName << QualType(OPT, 0));
2127 return HandleExprPropertyRefExpr(OPT, BaseExpr, OpLoc,
2128 TypoResult, MemberLoc,
2129 SuperLoc, SuperType, Super);
2130 }
2131 }
2132 ObjCInterfaceDecl *ClassDeclared;
2133 if (ObjCIvarDecl *Ivar =
2134 IFace->lookupInstanceVariable(Member, ClassDeclared)) {
2135 QualType T = Ivar->getType();
2136 if (const ObjCObjectPointerType * OBJPT =
2138 if (RequireCompleteType(MemberLoc, OBJPT->getPointeeType(),
2139 diag::err_property_not_as_forward_class,
2140 MemberName, BaseExpr))
2141 return ExprError();
2142 }
2143 Diag(MemberLoc,
2144 diag::err_ivar_access_using_property_syntax_suggest)
2145 << MemberName << QualType(OPT, 0) << Ivar->getDeclName()
2146 << FixItHint::CreateReplacement(OpLoc, "->");
2147 return ExprError();
2148 }
2149
2150 Diag(MemberLoc, diag::err_property_not_found)
2151 << MemberName << QualType(OPT, 0);
2152 if (Setter)
2153 Diag(Setter->getLocation(), diag::note_getter_unavailable)
2154 << MemberName << BaseExpr->getSourceRange();
2155 return ExprError();
2156}
2157
2160 IdentifierInfo &propertyName,
2161 SourceLocation receiverNameLoc,
2162 SourceLocation propertyNameLoc) {
2163
2164 IdentifierInfo *receiverNamePtr = &receiverName;
2165 ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(receiverNamePtr,
2166 receiverNameLoc);
2167
2168 QualType SuperType;
2169 if (!IFace) {
2170 // If the "receiver" is 'super' in a method, handle it as an expression-like
2171 // property reference.
2172 if (receiverNamePtr->isStr("super")) {
2173 if (ObjCMethodDecl *CurMethod = tryCaptureObjCSelf(receiverNameLoc)) {
2174 if (auto classDecl = CurMethod->getClassInterface()) {
2175 SuperType = QualType(classDecl->getSuperClassType(), 0);
2176 if (CurMethod->isInstanceMethod()) {
2177 if (SuperType.isNull()) {
2178 // The current class does not have a superclass.
2179 Diag(receiverNameLoc, diag::err_root_class_cannot_use_super)
2180 << CurMethod->getClassInterface()->getIdentifier();
2181 return ExprError();
2182 }
2184
2186 /*BaseExpr*/nullptr,
2187 SourceLocation()/*OpLoc*/,
2188 &propertyName,
2189 propertyNameLoc,
2190 receiverNameLoc, T, true);
2191 }
2192
2193 // Otherwise, if this is a class method, try dispatching to our
2194 // superclass.
2195 IFace = CurMethod->getClassInterface()->getSuperClass();
2196 }
2197 }
2198 }
2199
2200 if (!IFace) {
2201 Diag(receiverNameLoc, diag::err_expected_either) << tok::identifier
2202 << tok::l_paren;
2203 return ExprError();
2204 }
2205 }
2206
2207 Selector GetterSel;
2208 Selector SetterSel;
2209 if (auto PD = IFace->FindPropertyDeclaration(
2211 GetterSel = PD->getGetterName();
2212 SetterSel = PD->getSetterName();
2213 } else {
2214 GetterSel = PP.getSelectorTable().getNullarySelector(&propertyName);
2216 PP.getIdentifierTable(), PP.getSelectorTable(), &propertyName);
2217 }
2218
2219 // Search for a declared property first.
2220 ObjCMethodDecl *Getter = IFace->lookupClassMethod(GetterSel);
2221
2222 // If this reference is in an @implementation, check for 'private' methods.
2223 if (!Getter)
2224 Getter = IFace->lookupPrivateClassMethod(GetterSel);
2225
2226 if (Getter) {
2227 // FIXME: refactor/share with ActOnMemberReference().
2228 // Check if we can reference this property.
2229 if (DiagnoseUseOfDecl(Getter, propertyNameLoc))
2230 return ExprError();
2231 }
2232
2233 // Look for the matching setter, in case it is needed.
2234 ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
2235 if (!Setter) {
2236 // If this reference is in an @implementation, also check for 'private'
2237 // methods.
2238 Setter = IFace->lookupPrivateClassMethod(SetterSel);
2239 }
2240 // Look through local category implementations associated with the class.
2241 if (!Setter)
2242 Setter = IFace->getCategoryClassMethod(SetterSel);
2243
2244 if (Setter && DiagnoseUseOfDecl(Setter, propertyNameLoc))
2245 return ExprError();
2246
2247 if (Getter || Setter) {
2248 if (!SuperType.isNull())
2249 return new (Context)
2251 OK_ObjCProperty, propertyNameLoc, receiverNameLoc,
2252 SuperType);
2253
2254 return new (Context) ObjCPropertyRefExpr(
2256 propertyNameLoc, receiverNameLoc, IFace);
2257 }
2258 return ExprError(Diag(propertyNameLoc, diag::err_property_not_found)
2259 << &propertyName << Context.getObjCInterfaceType(IFace));
2260}
2261
2262namespace {
2263
2264class ObjCInterfaceOrSuperCCC final : public CorrectionCandidateCallback {
2265 public:
2266 ObjCInterfaceOrSuperCCC(ObjCMethodDecl *Method) {
2267 // Determine whether "super" is acceptable in the current context.
2268 if (Method && Method->getClassInterface())
2269 WantObjCSuper = Method->getClassInterface()->getSuperClass();
2270 }
2271
2272 bool ValidateCandidate(const TypoCorrection &candidate) override {
2273 return candidate.getCorrectionDeclAs<ObjCInterfaceDecl>() ||
2274 candidate.isKeyword("super");
2275 }
2276
2277 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2278 return std::make_unique<ObjCInterfaceOrSuperCCC>(*this);
2279 }
2280};
2281
2282} // end anonymous namespace
2283
2285 IdentifierInfo *Name,
2286 SourceLocation NameLoc,
2287 bool IsSuper,
2288 bool HasTrailingDot,
2289 ParsedType &ReceiverType) {
2290 ReceiverType = nullptr;
2291
2292 // If the identifier is "super" and there is no trailing dot, we're
2293 // messaging super. If the identifier is "super" and there is a
2294 // trailing dot, it's an instance message.
2295 if (IsSuper && S->isInObjcMethodScope())
2296 return HasTrailingDot? ObjCInstanceMessage : ObjCSuperMessage;
2297
2298 LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName);
2299 LookupName(Result, S);
2300
2301 switch (Result.getResultKind()) {
2303 // Normal name lookup didn't find anything. If we're in an
2304 // Objective-C method, look for ivars. If we find one, we're done!
2305 // FIXME: This is a hack. Ivar lookup should be part of normal
2306 // lookup.
2307 if (ObjCMethodDecl *Method = getCurMethodDecl()) {
2308 if (!Method->getClassInterface()) {
2309 // Fall back: let the parser try to parse it as an instance message.
2310 return ObjCInstanceMessage;
2311 }
2312
2313 ObjCInterfaceDecl *ClassDeclared;
2314 if (Method->getClassInterface()->lookupInstanceVariable(Name,
2315 ClassDeclared))
2316 return ObjCInstanceMessage;
2317 }
2318
2319 // Break out; we'll perform typo correction below.
2320 break;
2321
2326 Result.suppressDiagnostics();
2327 return ObjCInstanceMessage;
2328
2329 case LookupResult::Found: {
2330 // If the identifier is a class or not, and there is a trailing dot,
2331 // it's an instance message.
2332 if (HasTrailingDot)
2333 return ObjCInstanceMessage;
2334 // We found something. If it's a type, then we have a class
2335 // message. Otherwise, it's an instance message.
2336 NamedDecl *ND = Result.getFoundDecl();
2337 QualType T;
2338 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(ND))
2340 else if (TypeDecl *Type = dyn_cast<TypeDecl>(ND)) {
2342 DiagnoseUseOfDecl(Type, NameLoc);
2343 }
2344 else
2345 return ObjCInstanceMessage;
2346
2347 // We have a class message, and T is the type we're
2348 // messaging. Build source-location information for it.
2349 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
2350 ReceiverType = CreateParsedType(T, TSInfo);
2351 return ObjCClassMessage;
2352 }
2353 }
2354
2355 ObjCInterfaceOrSuperCCC CCC(getCurMethodDecl());
2356 if (TypoCorrection Corrected = CorrectTypo(
2357 Result.getLookupNameInfo(), Result.getLookupKind(), S, nullptr, CCC,
2358 CTK_ErrorRecovery, nullptr, false, nullptr, false)) {
2359 if (Corrected.isKeyword()) {
2360 // If we've found the keyword "super" (the only keyword that would be
2361 // returned by CorrectTypo), this is a send to super.
2362 diagnoseTypo(Corrected,
2363 PDiag(diag::err_unknown_receiver_suggest) << Name);
2364 return ObjCSuperMessage;
2365 } else if (ObjCInterfaceDecl *Class =
2366 Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) {
2367 // If we found a declaration, correct when it refers to an Objective-C
2368 // class.
2369 diagnoseTypo(Corrected,
2370 PDiag(diag::err_unknown_receiver_suggest) << Name);
2372 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
2373 ReceiverType = CreateParsedType(T, TSInfo);
2374 return ObjCClassMessage;
2375 }
2376 }
2377
2378 // Fall back: let the parser try to parse it as an instance message.
2379 return ObjCInstanceMessage;
2380}
2381
2383 SourceLocation SuperLoc,
2384 Selector Sel,
2385 SourceLocation LBracLoc,
2386 ArrayRef<SourceLocation> SelectorLocs,
2387 SourceLocation RBracLoc,
2388 MultiExprArg Args) {
2389 // Determine whether we are inside a method or not.
2390 ObjCMethodDecl *Method = tryCaptureObjCSelf(SuperLoc);
2391 if (!Method) {
2392 Diag(SuperLoc, diag::err_invalid_receiver_to_message_super);
2393 return ExprError();
2394 }
2395
2397 if (!Class) {
2398 Diag(SuperLoc, diag::err_no_super_class_message)
2399 << Method->getDeclName();
2400 return ExprError();
2401 }
2402
2403 QualType SuperTy(Class->getSuperClassType(), 0);
2404 if (SuperTy.isNull()) {
2405 // The current class does not have a superclass.
2406 Diag(SuperLoc, diag::err_root_class_cannot_use_super)
2407 << Class->getIdentifier();
2408 return ExprError();
2409 }
2410
2411 // We are in a method whose class has a superclass, so 'super'
2412 // is acting as a keyword.
2413 if (Method->getSelector() == Sel)
2415
2416 if (Method->isInstanceMethod()) {
2417 // Since we are in an instance method, this is an instance
2418 // message to the superclass instance.
2419 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2420 return BuildInstanceMessage(nullptr, SuperTy, SuperLoc,
2421 Sel, /*Method=*/nullptr,
2422 LBracLoc, SelectorLocs, RBracLoc, Args);
2423 }
2424
2425 // Since we are in a class method, this is a class message to
2426 // the superclass.
2427 return BuildClassMessage(/*ReceiverTypeInfo=*/nullptr,
2428 SuperTy,
2429 SuperLoc, Sel, /*Method=*/nullptr,
2430 LBracLoc, SelectorLocs, RBracLoc, Args);
2431}
2432
2434 bool isSuperReceiver,
2435 SourceLocation Loc,
2436 Selector Sel,
2437 ObjCMethodDecl *Method,
2438 MultiExprArg Args) {
2439 TypeSourceInfo *receiverTypeInfo = nullptr;
2440 if (!ReceiverType.isNull())
2441 receiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType);
2442
2443 assert(((isSuperReceiver && Loc.isValid()) || receiverTypeInfo) &&
2444 "Either the super receiver location needs to be valid or the receiver "
2445 "needs valid type source information");
2446 return BuildClassMessage(receiverTypeInfo, ReceiverType,
2447 /*SuperLoc=*/isSuperReceiver ? Loc : SourceLocation(),
2448 Sel, Method, Loc, Loc, Loc, Args,
2449 /*isImplicit=*/true);
2450}
2451
2452static void applyCocoaAPICheck(Sema &S, const ObjCMessageExpr *Msg,
2453 unsigned DiagID,
2454 bool (*refactor)(const ObjCMessageExpr *,
2455 const NSAPI &, edit::Commit &)) {
2456 SourceLocation MsgLoc = Msg->getExprLoc();
2457 if (S.Diags.isIgnored(DiagID, MsgLoc))
2458 return;
2459
2461 edit::Commit ECommit(SM, S.LangOpts);
2462 if (refactor(Msg,*S.NSAPIObj, ECommit)) {
2463 auto Builder = S.Diag(MsgLoc, DiagID)
2464 << Msg->getSelector() << Msg->getSourceRange();
2465 // FIXME: Don't emit diagnostic at all if fixits are non-commitable.
2466 if (!ECommit.isCommitable())
2467 return;
2469 I = ECommit.edit_begin(), E = ECommit.edit_end(); I != E; ++I) {
2470 const edit::Commit::Edit &Edit = *I;
2471 switch (Edit.Kind) {
2473 Builder.AddFixItHint(FixItHint::CreateInsertion(Edit.OrigLoc,
2474 Edit.Text,
2475 Edit.BeforePrev));
2476 break;
2478 Builder.AddFixItHint(
2480 Edit.getInsertFromRange(SM),
2481 Edit.BeforePrev));
2482 break;
2484 Builder.AddFixItHint(FixItHint::CreateRemoval(Edit.getFileRange(SM)));
2485 break;
2486 }
2487 }
2488 }
2489}
2490
2491static void checkCocoaAPI(Sema &S, const ObjCMessageExpr *Msg) {
2492 applyCocoaAPICheck(S, Msg, diag::warn_objc_redundant_literal_use,
2494}
2495
2497 const ObjCMethodDecl *Method,
2498 ArrayRef<Expr *> Args, QualType ReceiverType,
2499 bool IsClassObjectCall) {
2500 // Check if this is a performSelector method that uses a selector that returns
2501 // a record or a vector type.
2502 if (Method->getSelector().getMethodFamily() != OMF_performSelector ||
2503 Args.empty())
2504 return;
2505 const auto *SE = dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens());
2506 if (!SE)
2507 return;
2508 ObjCMethodDecl *ImpliedMethod;
2509 if (!IsClassObjectCall) {
2510 const auto *OPT = ReceiverType->getAs<ObjCObjectPointerType>();
2511 if (!OPT || !OPT->getInterfaceDecl())
2512 return;
2513 ImpliedMethod =
2514 OPT->getInterfaceDecl()->lookupInstanceMethod(SE->getSelector());
2515 if (!ImpliedMethod)
2516 ImpliedMethod =
2517 OPT->getInterfaceDecl()->lookupPrivateMethod(SE->getSelector());
2518 } else {
2519 const auto *IT = ReceiverType->getAs<ObjCInterfaceType>();
2520 if (!IT)
2521 return;
2522 ImpliedMethod = IT->getDecl()->lookupClassMethod(SE->getSelector());
2523 if (!ImpliedMethod)
2524 ImpliedMethod =
2525 IT->getDecl()->lookupPrivateClassMethod(SE->getSelector());
2526 }
2527 if (!ImpliedMethod)
2528 return;
2529 QualType Ret = ImpliedMethod->getReturnType();
2530 if (Ret->isRecordType() || Ret->isVectorType() || Ret->isExtVectorType()) {
2531 S.Diag(Loc, diag::warn_objc_unsafe_perform_selector)
2532 << Method->getSelector()
2533 << (!Ret->isRecordType()
2534 ? /*Vector*/ 2
2535 : Ret->isUnionType() ? /*Union*/ 1 : /*Struct*/ 0);
2536 S.Diag(ImpliedMethod->getBeginLoc(),
2537 diag::note_objc_unsafe_perform_selector_method_declared_here)
2538 << ImpliedMethod->getSelector() << Ret;
2539 }
2540}
2541
2542/// Diagnose use of %s directive in an NSString which is being passed
2543/// as formatting string to formatting method.
2544static void
2546 ObjCMethodDecl *Method,
2547 Selector Sel,
2548 Expr **Args, unsigned NumArgs) {
2549 unsigned Idx = 0;
2550 bool Format = false;
2552 if (SFFamily == ObjCStringFormatFamily::SFF_NSString) {
2553 Idx = 0;
2554 Format = true;
2555 }
2556 else if (Method) {
2557 for (const auto *I : Method->specific_attrs<FormatAttr>()) {
2558 if (S.GetFormatNSStringIdx(I, Idx)) {
2559 Format = true;
2560 break;
2561 }
2562 }
2563 }
2564 if (!Format || NumArgs <= Idx)
2565 return;
2566
2567 Expr *FormatExpr = Args[Idx];
2568 if (ObjCStringLiteral *OSL =
2569 dyn_cast<ObjCStringLiteral>(FormatExpr->IgnoreParenImpCasts())) {
2570 StringLiteral *FormatString = OSL->getString();
2571 if (S.FormatStringHasSArg(FormatString)) {
2572 S.Diag(FormatExpr->getExprLoc(), diag::warn_objc_cdirective_format_string)
2573 << "%s" << 0 << 0;
2574 if (Method)
2575 S.Diag(Method->getLocation(), diag::note_method_declared_at)
2576 << Method->getDeclName();
2577 }
2578 }
2579}
2580
2581/// Build an Objective-C class message expression.
2582///
2583/// This routine takes care of both normal class messages and
2584/// class messages to the superclass.
2585///
2586/// \param ReceiverTypeInfo Type source information that describes the
2587/// receiver of this message. This may be NULL, in which case we are
2588/// sending to the superclass and \p SuperLoc must be a valid source
2589/// location.
2590
2591/// \param ReceiverType The type of the object receiving the
2592/// message. When \p ReceiverTypeInfo is non-NULL, this is the same
2593/// type as that refers to. For a superclass send, this is the type of
2594/// the superclass.
2595///
2596/// \param SuperLoc The location of the "super" keyword in a
2597/// superclass message.
2598///
2599/// \param Sel The selector to which the message is being sent.
2600///
2601/// \param Method The method that this class message is invoking, if
2602/// already known.
2603///
2604/// \param LBracLoc The location of the opening square bracket ']'.
2605///
2606/// \param RBracLoc The location of the closing square bracket ']'.
2607///
2608/// \param ArgsIn The message arguments.
2610 QualType ReceiverType,
2611 SourceLocation SuperLoc,
2612 Selector Sel,
2613 ObjCMethodDecl *Method,
2614 SourceLocation LBracLoc,
2615 ArrayRef<SourceLocation> SelectorLocs,
2616 SourceLocation RBracLoc,
2617 MultiExprArg ArgsIn,
2618 bool isImplicit) {
2619 SourceLocation Loc = SuperLoc.isValid()? SuperLoc
2620 : ReceiverTypeInfo->getTypeLoc().getSourceRange().getBegin();
2621 if (LBracLoc.isInvalid()) {
2622 Diag(Loc, diag::err_missing_open_square_message_send)
2623 << FixItHint::CreateInsertion(Loc, "[");
2624 LBracLoc = Loc;
2625 }
2626 ArrayRef<SourceLocation> SelectorSlotLocs;
2627 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2628 SelectorSlotLocs = SelectorLocs;
2629 else
2630 SelectorSlotLocs = Loc;
2631 SourceLocation SelLoc = SelectorSlotLocs.front();
2632
2633 if (ReceiverType->isDependentType()) {
2634 // If the receiver type is dependent, we can't type-check anything
2635 // at this point. Build a dependent expression.
2636 unsigned NumArgs = ArgsIn.size();
2637 Expr **Args = ArgsIn.data();
2638 assert(SuperLoc.isInvalid() && "Message to super with dependent type");
2639 return ObjCMessageExpr::Create(Context, ReceiverType, VK_PRValue, LBracLoc,
2640 ReceiverTypeInfo, Sel, SelectorLocs,
2641 /*Method=*/nullptr, ArrayRef(Args, NumArgs),
2642 RBracLoc, isImplicit);
2643 }
2644
2645 // Find the class to which we are sending this message.
2646 ObjCInterfaceDecl *Class = nullptr;
2647 const ObjCObjectType *ClassType = ReceiverType->getAs<ObjCObjectType>();
2648 if (!ClassType || !(Class = ClassType->getInterface())) {
2649 Diag(Loc, diag::err_invalid_receiver_class_message)
2650 << ReceiverType;
2651 return ExprError();
2652 }
2653 assert(Class && "We don't know which class we're messaging?");
2654 // objc++ diagnoses during typename annotation.
2655 if (!getLangOpts().CPlusPlus)
2656 (void)DiagnoseUseOfDecl(Class, SelectorSlotLocs);
2657 // Find the method we are messaging.
2658 if (!Method) {
2659 SourceRange TypeRange
2660 = SuperLoc.isValid()? SourceRange(SuperLoc)
2661 : ReceiverTypeInfo->getTypeLoc().getSourceRange();
2663 (getLangOpts().ObjCAutoRefCount
2664 ? diag::err_arc_receiver_forward_class
2665 : diag::warn_receiver_forward_class),
2666 TypeRange)) {
2667 // A forward class used in messaging is treated as a 'Class'
2669 SourceRange(LBracLoc, RBracLoc));
2670 if (Method && !getLangOpts().ObjCAutoRefCount)
2671 Diag(Method->getLocation(), diag::note_method_sent_forward_class)
2672 << Method->getDeclName();
2673 }
2674 if (!Method)
2675 Method = Class->lookupClassMethod(Sel);
2676
2677 // If we have an implementation in scope, check "private" methods.
2678 if (!Method)
2679 Method = Class->lookupPrivateClassMethod(Sel);
2680
2681 if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs,
2682 nullptr, false, false, Class))
2683 return ExprError();
2684 }
2685
2686 // Check the argument types and determine the result type.
2687 QualType ReturnType;
2689
2690 unsigned NumArgs = ArgsIn.size();
2691 Expr **Args = ArgsIn.data();
2692 if (CheckMessageArgumentTypes(/*Receiver=*/nullptr, ReceiverType,
2693 MultiExprArg(Args, NumArgs), Sel, SelectorLocs,
2694 Method, true, SuperLoc.isValid(), LBracLoc,
2695 RBracLoc, SourceRange(), ReturnType, VK))
2696 return ExprError();
2697
2698 if (Method && !Method->getReturnType()->isVoidType() &&
2699 RequireCompleteType(LBracLoc, Method->getReturnType(),
2700 diag::err_illegal_message_expr_incomplete_type))
2701 return ExprError();
2702
2703 if (Method && Method->isDirectMethod() && SuperLoc.isValid()) {
2704 Diag(SuperLoc, diag::err_messaging_super_with_direct_method)
2706 SuperLoc, getLangOpts().ObjCAutoRefCount
2707 ? "self"
2708 : Method->getClassInterface()->getName());
2709 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
2710 << Method->getDeclName();
2711 }
2712
2713 // Warn about explicit call of +initialize on its own class. But not on 'super'.
2714 if (Method && Method->getMethodFamily() == OMF_initialize) {
2715 if (!SuperLoc.isValid()) {
2716 const ObjCInterfaceDecl *ID =
2717 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext());
2718 if (ID == Class) {
2719 Diag(Loc, diag::warn_direct_initialize_call);
2720 Diag(Method->getLocation(), diag::note_method_declared_at)
2721 << Method->getDeclName();
2722 }
2723 }
2724 else if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
2725 // [super initialize] is allowed only within an +initialize implementation
2726 if (CurMeth->getMethodFamily() != OMF_initialize) {
2727 Diag(Loc, diag::warn_direct_super_initialize_call);
2728 Diag(Method->getLocation(), diag::note_method_declared_at)
2729 << Method->getDeclName();
2730 Diag(CurMeth->getLocation(), diag::note_method_declared_at)
2731 << CurMeth->getDeclName();
2732 }
2733 }
2734 }
2735
2736 DiagnoseCStringFormatDirectiveInObjCAPI(*this, Method, Sel, Args, NumArgs);
2737
2738 // Construct the appropriate ObjCMessageExpr.
2740 if (SuperLoc.isValid())
2742 Context, ReturnType, VK, LBracLoc, SuperLoc, /*IsInstanceSuper=*/false,
2743 ReceiverType, Sel, SelectorLocs, Method, ArrayRef(Args, NumArgs),
2744 RBracLoc, isImplicit);
2745 else {
2747 Context, ReturnType, VK, LBracLoc, ReceiverTypeInfo, Sel, SelectorLocs,
2748 Method, ArrayRef(Args, NumArgs), RBracLoc, isImplicit);
2749 if (!isImplicit)
2750 checkCocoaAPI(*this, Result);
2751 }
2752 if (Method)
2753 checkFoundationAPI(*this, SelLoc, Method, ArrayRef(Args, NumArgs),
2754 ReceiverType, /*IsClassObjectCall=*/true);
2756}
2757
2758// ActOnClassMessage - used for both unary and keyword messages.
2759// ArgExprs is optional - if it is present, the number of expressions
2760// is obtained from Sel.getNumArgs().
2762 ParsedType Receiver,
2763 Selector Sel,
2764 SourceLocation LBracLoc,
2765 ArrayRef<SourceLocation> SelectorLocs,
2766 SourceLocation RBracLoc,
2767 MultiExprArg Args) {
2768 TypeSourceInfo *ReceiverTypeInfo;
2769 QualType ReceiverType = GetTypeFromParser(Receiver, &ReceiverTypeInfo);
2770 if (ReceiverType.isNull())
2771 return ExprError();
2772
2773 if (!ReceiverTypeInfo)
2774 ReceiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType, LBracLoc);
2775
2776 return BuildClassMessage(ReceiverTypeInfo, ReceiverType,
2777 /*SuperLoc=*/SourceLocation(), Sel,
2778 /*Method=*/nullptr, LBracLoc, SelectorLocs, RBracLoc,
2779 Args);
2780}
2781
2783 QualType ReceiverType,
2784 SourceLocation Loc,
2785 Selector Sel,
2786 ObjCMethodDecl *Method,
2787 MultiExprArg Args) {
2788 return BuildInstanceMessage(Receiver, ReceiverType,
2789 /*SuperLoc=*/!Receiver ? Loc : SourceLocation(),
2790 Sel, Method, Loc, Loc, Loc, Args,
2791 /*isImplicit=*/true);
2792}
2793
2795 if (!S.NSAPIObj)
2796 return false;
2797 const auto *Protocol = dyn_cast<ObjCProtocolDecl>(M->getDeclContext());
2798 if (!Protocol)
2799 return false;
2800 const IdentifierInfo *II = S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject);
2801 if (const auto *RootClass = dyn_cast_or_null<ObjCInterfaceDecl>(
2802 S.LookupSingleName(S.TUScope, II, Protocol->getBeginLoc(),
2804 for (const ObjCProtocolDecl *P : RootClass->all_referenced_protocols()) {
2805 if (P->getCanonicalDecl() == Protocol->getCanonicalDecl())
2806 return true;
2807 }
2808 }
2809 return false;
2810}
2811
2812/// Build an Objective-C instance message expression.
2813///
2814/// This routine takes care of both normal instance messages and
2815/// instance messages to the superclass instance.
2816///
2817/// \param Receiver The expression that computes the object that will
2818/// receive this message. This may be empty, in which case we are
2819/// sending to the superclass instance and \p SuperLoc must be a valid
2820/// source location.
2821///
2822/// \param ReceiverType The (static) type of the object receiving the
2823/// message. When a \p Receiver expression is provided, this is the
2824/// same type as that expression. For a superclass instance send, this
2825/// is a pointer to the type of the superclass.
2826///
2827/// \param SuperLoc The location of the "super" keyword in a
2828/// superclass instance message.
2829///
2830/// \param Sel The selector to which the message is being sent.
2831///
2832/// \param Method The method that this instance message is invoking, if
2833/// already known.
2834///
2835/// \param LBracLoc The location of the opening square bracket ']'.
2836///
2837/// \param RBracLoc The location of the closing square bracket ']'.
2838///
2839/// \param ArgsIn The message arguments.
2841 QualType ReceiverType,
2842 SourceLocation SuperLoc,
2843 Selector Sel,
2844 ObjCMethodDecl *Method,
2845 SourceLocation LBracLoc,
2846 ArrayRef<SourceLocation> SelectorLocs,
2847 SourceLocation RBracLoc,
2848 MultiExprArg ArgsIn,
2849 bool isImplicit) {
2850 assert((Receiver || SuperLoc.isValid()) && "If the Receiver is null, the "
2851 "SuperLoc must be valid so we can "
2852 "use it instead.");
2853
2854 // The location of the receiver.
2855 SourceLocation Loc = SuperLoc.isValid() ? SuperLoc : Receiver->getBeginLoc();
2856 SourceRange RecRange =
2857 SuperLoc.isValid()? SuperLoc : Receiver->getSourceRange();
2858 ArrayRef<SourceLocation> SelectorSlotLocs;
2859 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2860 SelectorSlotLocs = SelectorLocs;
2861 else
2862 SelectorSlotLocs = Loc;
2863 SourceLocation SelLoc = SelectorSlotLocs.front();
2864
2865 if (LBracLoc.isInvalid()) {
2866 Diag(Loc, diag::err_missing_open_square_message_send)
2867 << FixItHint::CreateInsertion(Loc, "[");
2868 LBracLoc = Loc;
2869 }
2870
2871 // If we have a receiver expression, perform appropriate promotions
2872 // and determine receiver type.
2873 if (Receiver) {
2874 if (Receiver->hasPlaceholderType()) {
2876 if (Receiver->getType() == Context.UnknownAnyTy)
2878 else
2879 Result = CheckPlaceholderExpr(Receiver);
2880 if (Result.isInvalid()) return ExprError();
2881 Receiver = Result.get();
2882 }
2883
2884 if (Receiver->isTypeDependent()) {
2885 // If the receiver is type-dependent, we can't type-check anything
2886 // at this point. Build a dependent expression.
2887 unsigned NumArgs = ArgsIn.size();
2888 Expr **Args = ArgsIn.data();
2889 assert(SuperLoc.isInvalid() && "Message to super with dependent type");
2891 Context, Context.DependentTy, VK_PRValue, LBracLoc, Receiver, Sel,
2892 SelectorLocs, /*Method=*/nullptr, ArrayRef(Args, NumArgs), RBracLoc,
2893 isImplicit);
2894 }
2895
2896 // If necessary, apply function/array conversion to the receiver.
2897 // C99 6.7.5.3p[7,8].
2899 if (Result.isInvalid())
2900 return ExprError();
2901 Receiver = Result.get();
2902 ReceiverType = Receiver->getType();
2903
2904 // If the receiver is an ObjC pointer, a block pointer, or an
2905 // __attribute__((NSObject)) pointer, we don't need to do any
2906 // special conversion in order to look up a receiver.
2907 if (ReceiverType->isObjCRetainableType()) {
2908 // do nothing
2909 } else if (!getLangOpts().ObjCAutoRefCount &&
2911 (ReceiverType->isPointerType() ||
2912 ReceiverType->isIntegerType())) {
2913 // Implicitly convert integers and pointers to 'id' but emit a warning.
2914 // But not in ARC.
2915 Diag(Loc, diag::warn_bad_receiver_type) << ReceiverType << RecRange;
2916 if (ReceiverType->isPointerType()) {
2917 Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(),
2918 CK_CPointerToObjCPointerCast).get();
2919 } else {
2920 // TODO: specialized warning on null receivers?
2921 bool IsNull = Receiver->isNullPointerConstant(Context,
2923 CastKind Kind = IsNull ? CK_NullToPointer : CK_IntegralToPointer;
2924 Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(),
2925 Kind).get();
2926 }
2927 ReceiverType = Receiver->getType();
2928 } else if (getLangOpts().CPlusPlus) {
2929 // The receiver must be a complete type.
2930 if (RequireCompleteType(Loc, Receiver->getType(),
2931 diag::err_incomplete_receiver_type))
2932 return ExprError();
2933
2935 if (result.isUsable()) {
2936 Receiver = result.get();
2937 ReceiverType = Receiver->getType();
2938 }
2939 }
2940 }
2941
2942 // There's a somewhat weird interaction here where we assume that we
2943 // won't actually have a method unless we also don't need to do some
2944 // of the more detailed type-checking on the receiver.
2945
2946 if (!Method) {
2947 // Handle messages to id and __kindof types (where we use the
2948 // global method pool).
2949 const ObjCObjectType *typeBound = nullptr;
2950 bool receiverIsIdLike = ReceiverType->isObjCIdOrObjectKindOfType(Context,
2951 typeBound);
2952 if (receiverIsIdLike || ReceiverType->isBlockPointerType() ||
2953 (Receiver && Context.isObjCNSObjectType(Receiver->getType()))) {
2955 // If we have a type bound, further filter the methods.
2956 CollectMultipleMethodsInGlobalPool(Sel, Methods, true/*InstanceFirst*/,
2957 true/*CheckTheOther*/, typeBound);
2958 if (!Methods.empty()) {
2959 // We choose the first method as the initial candidate, then try to
2960 // select a better one.
2961 Method = Methods[0];
2962
2963 if (ObjCMethodDecl *BestMethod =
2964 SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(), Methods))
2965 Method = BestMethod;
2966
2967 if (!AreMultipleMethodsInGlobalPool(Sel, Method,
2968 SourceRange(LBracLoc, RBracLoc),
2969 receiverIsIdLike, Methods))
2970 DiagnoseUseOfDecl(Method, SelectorSlotLocs);
2971 }
2972 } else if (ReceiverType->isObjCClassOrClassKindOfType() ||
2973 ReceiverType->isObjCQualifiedClassType()) {
2974 // Handle messages to Class.
2975 // We allow sending a message to a qualified Class ("Class<foo>"), which
2976 // is ok as long as one of the protocols implements the selector (if not,
2977 // warn).
2978 if (!ReceiverType->isObjCClassOrClassKindOfType()) {
2979 const ObjCObjectPointerType *QClassTy
2980 = ReceiverType->getAsObjCQualifiedClassType();
2981 // Search protocols for class methods.
2982 Method = LookupMethodInQualifiedType(Sel, QClassTy, false);
2983 if (!Method) {
2984 Method = LookupMethodInQualifiedType(Sel, QClassTy, true);
2985 // warn if instance method found for a Class message.
2986 if (Method && !isMethodDeclaredInRootProtocol(*this, Method)) {
2987 Diag(SelLoc, diag::warn_instance_method_on_class_found)
2988 << Method->getSelector() << Sel;
2989 Diag(Method->getLocation(), diag::note_method_declared_at)
2990 << Method->getDeclName();
2991 }
2992 }
2993 } else {
2994 if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
2995 if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
2996 // As a guess, try looking for the method in the current interface.
2997 // This very well may not produce the "right" method.
2998
2999 // First check the public methods in the class interface.
3000 Method = ClassDecl->lookupClassMethod(Sel);
3001
3002 if (!Method)
3003 Method = ClassDecl->lookupPrivateClassMethod(Sel);
3004
3005 if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs))
3006 return ExprError();
3007 }
3008 }
3009 if (!Method) {
3010 // If not messaging 'self', look for any factory method named 'Sel'.
3011 if (!Receiver || !isSelfExpr(Receiver)) {
3012 // If no class (factory) method was found, check if an _instance_
3013 // method of the same name exists in the root class only.
3016 false/*InstanceFirst*/,
3017 true/*CheckTheOther*/);
3018 if (!Methods.empty()) {
3019 // We choose the first method as the initial candidate, then try
3020 // to select a better one.
3021 Method = Methods[0];
3022
3023 // If we find an instance method, emit warning.
3024 if (Method->isInstanceMethod()) {
3025 if (const ObjCInterfaceDecl *ID =
3026 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
3027 if (ID->getSuperClass())
3028 Diag(SelLoc, diag::warn_root_inst_method_not_found)
3029 << Sel << SourceRange(LBracLoc, RBracLoc);
3030 }
3031 }
3032
3033 if (ObjCMethodDecl *BestMethod =
3034 SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(),
3035 Methods))
3036 Method = BestMethod;
3037 }
3038 }
3039 }
3040 }
3041 } else {
3042 ObjCInterfaceDecl *ClassDecl = nullptr;
3043
3044 // We allow sending a message to a qualified ID ("id<foo>"), which is ok as
3045 // long as one of the protocols implements the selector (if not, warn).
3046 // And as long as message is not deprecated/unavailable (warn if it is).
3047 if (const ObjCObjectPointerType *QIdTy
3048 = ReceiverType->getAsObjCQualifiedIdType()) {
3049 // Search protocols for instance methods.
3050 Method = LookupMethodInQualifiedType(Sel, QIdTy, true);
3051 if (!Method)
3052 Method = LookupMethodInQualifiedType(Sel, QIdTy, false);
3053 if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs))
3054 return ExprError();
3055 } else if (const ObjCObjectPointerType *OCIType
3056 = ReceiverType->getAsObjCInterfacePointerType()) {
3057 // We allow sending a message to a pointer to an interface (an object).
3058 ClassDecl = OCIType->getInterfaceDecl();
3059
3060 // Try to complete the type. Under ARC, this is a hard error from which
3061 // we don't try to recover.
3062 // FIXME: In the non-ARC case, this will still be a hard error if the
3063 // definition is found in a module that's not visible.
3064 const ObjCInterfaceDecl *forwardClass = nullptr;
3065 if (RequireCompleteType(Loc, OCIType->getPointeeType(),
3066 getLangOpts().ObjCAutoRefCount
3067 ? diag::err_arc_receiver_forward_instance
3068 : diag::warn_receiver_forward_instance,
3069 RecRange)) {
3070 if (getLangOpts().ObjCAutoRefCount)
3071 return ExprError();
3072
3073 forwardClass = OCIType->getInterfaceDecl();
3074 Diag(Receiver ? Receiver->getBeginLoc() : SuperLoc,
3075 diag::note_receiver_is_id);
3076 Method = nullptr;
3077 } else {
3078 Method = ClassDecl->lookupInstanceMethod(Sel);
3079 }
3080
3081 if (!Method)
3082 // Search protocol qualifiers.
3083 Method = LookupMethodInQualifiedType(Sel, OCIType, true);
3084
3085 if (!Method) {
3086 // If we have implementations in scope, check "private" methods.
3087 Method = ClassDecl->lookupPrivateMethod(Sel);
3088
3089 if (!Method && getLangOpts().ObjCAutoRefCount) {
3090 Diag(SelLoc, diag::err_arc_may_not_respond)
3091 << OCIType->getPointeeType() << Sel << RecRange
3092 << SourceRange(SelectorLocs.front(), SelectorLocs.back());
3093 return ExprError();
3094 }
3095
3096 if (!Method && (!Receiver || !isSelfExpr(Receiver))) {
3097 // If we still haven't found a method, look in the global pool. This
3098 // behavior isn't very desirable, however we need it for GCC
3099 // compatibility. FIXME: should we deviate??
3100 if (OCIType->qual_empty()) {
3103 true/*InstanceFirst*/,
3104 false/*CheckTheOther*/);
3105 if (!Methods.empty()) {
3106 // We choose the first method as the initial candidate, then try
3107 // to select a better one.
3108 Method = Methods[0];
3109
3110 if (ObjCMethodDecl *BestMethod =
3111 SelectBestMethod(Sel, ArgsIn, Method->isInstanceMethod(),
3112 Methods))
3113 Method = BestMethod;
3114
3116 SourceRange(LBracLoc, RBracLoc),
3117 true/*receiverIdOrClass*/,
3118 Methods);
3119 }
3120 if (Method && !forwardClass)
3121 Diag(SelLoc, diag::warn_maynot_respond)
3122 << OCIType->getInterfaceDecl()->getIdentifier()
3123 << Sel << RecRange;
3124 }
3125 }
3126 }
3127 if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs, forwardClass))
3128 return ExprError();
3129 } else {
3130 // Reject other random receiver types (e.g. structs).
3131 Diag(Loc, diag::err_bad_receiver_type) << ReceiverType << RecRange;
3132 return ExprError();
3133 }
3134 }
3135 }
3136
3137 FunctionScopeInfo *DIFunctionScopeInfo =
3138 (Method && Method->getMethodFamily() == OMF_init)
3139 ? getEnclosingFunction() : nullptr;
3140
3141 if (Method && Method->isDirectMethod()) {
3142 if (ReceiverType->isObjCIdType() && !isImplicit) {
3143 Diag(Receiver->getExprLoc(),
3144 diag::err_messaging_unqualified_id_with_direct_method);
3145 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
3146 << Method->getDeclName();
3147 }
3148
3149 // Under ARC, self can't be assigned, and doing a direct call to `self`
3150 // when it's a Class is hence safe. For other cases, we can't trust `self`
3151 // is what we think it is, so we reject it.
3152 if (ReceiverType->isObjCClassType() && !isImplicit &&
3153 !(Receiver->isObjCSelfExpr() && getLangOpts().ObjCAutoRefCount)) {
3154 {
3155 auto Builder = Diag(Receiver->getExprLoc(),
3156 diag::err_messaging_class_with_direct_method);
3157 if (Receiver->isObjCSelfExpr()) {
3158 Builder.AddFixItHint(FixItHint::CreateReplacement(
3159 RecRange, Method->getClassInterface()->getName()));
3160 }
3161 }
3162 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
3163 << Method->getDeclName();
3164 }
3165
3166 if (SuperLoc.isValid()) {
3167 {
3168 auto Builder =
3169 Diag(SuperLoc, diag::err_messaging_super_with_direct_method);
3170 if (ReceiverType->isObjCClassType()) {
3171 Builder.AddFixItHint(FixItHint::CreateReplacement(
3172 SuperLoc, Method->getClassInterface()->getName()));
3173 } else {
3174 Builder.AddFixItHint(FixItHint::CreateReplacement(SuperLoc, "self"));
3175 }
3176 }
3177 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
3178 << Method->getDeclName();
3179 }
3180 } else if (ReceiverType->isObjCIdType() && !isImplicit) {
3181 Diag(Receiver->getExprLoc(), diag::warn_messaging_unqualified_id);
3182 }
3183
3184 if (DIFunctionScopeInfo &&
3185 DIFunctionScopeInfo->ObjCIsDesignatedInit &&
3186 (SuperLoc.isValid() || isSelfExpr(Receiver))) {
3187 bool isDesignatedInitChain = false;
3188 if (SuperLoc.isValid()) {
3189 if (const ObjCObjectPointerType *
3190 OCIType = ReceiverType->getAsObjCInterfacePointerType()) {
3191 if (const ObjCInterfaceDecl *ID = OCIType->getInterfaceDecl()) {
3192 // Either we know this is a designated initializer or we
3193 // conservatively assume it because we don't know for sure.
3194 if (!ID->declaresOrInheritsDesignatedInitializers() ||
3195 ID->isDesignatedInitializer(Sel)) {
3196 isDesignatedInitChain = true;
3197 DIFunctionScopeInfo->ObjCWarnForNoDesignatedInitChain = false;
3198 }
3199 }
3200 }
3201 }
3202 if (!isDesignatedInitChain) {
3203 const ObjCMethodDecl *InitMethod = nullptr;
3204 bool isDesignated =
3206 assert(isDesignated && InitMethod);
3207 (void)isDesignated;
3208 Diag(SelLoc, SuperLoc.isValid() ?
3209 diag::warn_objc_designated_init_non_designated_init_call :
3210 diag::warn_objc_designated_init_non_super_designated_init_call);
3211 Diag(InitMethod->getLocation(),
3212 diag::note_objc_designated_init_marked_here);
3213 }
3214 }
3215
3216 if (DIFunctionScopeInfo &&
3217 DIFunctionScopeInfo->ObjCIsSecondaryInit &&
3218 (SuperLoc.isValid() || isSelfExpr(Receiver))) {
3219 if (SuperLoc.isValid()) {
3220 Diag(SelLoc, diag::warn_objc_secondary_init_super_init_call);
3221 } else {
3222 DIFunctionScopeInfo->ObjCWarnForNoInitDelegation = false;
3223 }
3224 }
3225
3226 // Check the message arguments.
3227 unsigned NumArgs = ArgsIn.size();
3228 Expr **Args = ArgsIn.data();
3229 QualType ReturnType;
3231 bool ClassMessage = (ReceiverType->isObjCClassType() ||
3232 ReceiverType->isObjCQualifiedClassType());
3233 if (CheckMessageArgumentTypes(Receiver, ReceiverType,
3234 MultiExprArg(Args, NumArgs), Sel, SelectorLocs,
3235 Method, ClassMessage, SuperLoc.isValid(),
3236 LBracLoc, RBracLoc, RecRange, ReturnType, VK))
3237 return ExprError();
3238
3239 if (Method && !Method->getReturnType()->isVoidType() &&
3240 RequireCompleteType(LBracLoc, Method->getReturnType(),
3241 diag::err_illegal_message_expr_incomplete_type))
3242 return ExprError();
3243
3244 // In ARC, forbid the user from sending messages to
3245 // retain/release/autorelease/dealloc/retainCount explicitly.
3246 if (getLangOpts().ObjCAutoRefCount) {
3247 ObjCMethodFamily family =
3248 (Method ? Method->getMethodFamily() : Sel.getMethodFamily());
3249 switch (family) {
3250 case OMF_init:
3251 if (Method)
3252 checkInitMethod(Method, ReceiverType);
3253 break;
3254
3255 case OMF_None:
3256 case OMF_alloc:
3257 case OMF_copy:
3258 case OMF_finalize:
3259 case OMF_mutableCopy:
3260 case OMF_new:
3261 case OMF_self:
3262 case OMF_initialize:
3263 break;
3264
3265 case OMF_dealloc:
3266 case OMF_retain:
3267 case OMF_release:
3268 case OMF_autorelease:
3269 case OMF_retainCount:
3270 Diag(SelLoc, diag::err_arc_illegal_explicit_message)
3271 << Sel << RecRange;
3272 break;
3273
3275 if (Method && NumArgs >= 1) {
3276 if (const auto *SelExp =
3277 dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens())) {
3278 Selector ArgSel = SelExp->getSelector();
3279 ObjCMethodDecl *SelMethod =
3281 SelExp->getSourceRange());
3282 if (!SelMethod)
3283 SelMethod =
3285 SelExp->getSourceRange());
3286 if (SelMethod) {
3287 ObjCMethodFamily SelFamily = SelMethod->getMethodFamily();
3288 switch (SelFamily) {
3289 case OMF_alloc:
3290 case OMF_copy:
3291 case OMF_mutableCopy:
3292 case OMF_new:
3293 case OMF_init:
3294 // Issue error, unless ns_returns_not_retained.
3295 if (!SelMethod->hasAttr<NSReturnsNotRetainedAttr>()) {
3296 // selector names a +1 method
3297 Diag(SelLoc,
3298 diag::err_arc_perform_selector_retains);
3299 Diag(SelMethod->getLocation(), diag::note_method_declared_at)
3300 << SelMethod->getDeclName();
3301 }
3302 break;
3303 default:
3304 // +0 call. OK. unless ns_returns_retained.
3305 if (SelMethod->hasAttr<NSReturnsRetainedAttr>()) {
3306 // selector names a +1 method
3307 Diag(SelLoc,
3308 diag::err_arc_perform_selector_retains);
3309 Diag(SelMethod->getLocation(), diag::note_method_declared_at)
3310 << SelMethod->getDeclName();
3311 }
3312 break;
3313 }
3314 }
3315 } else {
3316 // error (may leak).
3317 Diag(SelLoc, diag::warn_arc_perform_selector_leaks);
3318 Diag(Args[0]->getExprLoc(), diag::note_used_here);
3319 }
3320 }
3321 break;
3322 }
3323 }
3324
3325 DiagnoseCStringFormatDirectiveInObjCAPI(*this, Method, Sel, Args, NumArgs);
3326
3327 // Construct the appropriate ObjCMessageExpr instance.
3329 if (SuperLoc.isValid())
3331 Context, ReturnType, VK, LBracLoc, SuperLoc, /*IsInstanceSuper=*/true,
3332 ReceiverType, Sel, SelectorLocs, Method, ArrayRef(Args, NumArgs),
3333 RBracLoc, isImplicit);
3334 else {
3336 Context, ReturnType, VK, LBracLoc, Receiver, Sel, SelectorLocs, Method,
3337 ArrayRef(Args, NumArgs), RBracLoc, isImplicit);
3338 if (!isImplicit)
3339 checkCocoaAPI(*this, Result);
3340 }
3341 if (Method) {
3342 bool IsClassObjectCall = ClassMessage;
3343 // 'self' message receivers in class methods should be treated as message
3344 // sends to the class object in order for the semantic checks to be
3345 // performed correctly. Messages to 'super' already count as class messages,
3346 // so they don't need to be handled here.
3347 if (Receiver && isSelfExpr(Receiver)) {
3348 if (const auto *OPT = ReceiverType->getAs<ObjCObjectPointerType>()) {
3349 if (OPT->getObjectType()->isObjCClass()) {
3350 if (const auto *CurMeth = getCurMethodDecl()) {
3351 IsClassObjectCall = true;
3352 ReceiverType =
3353 Context.getObjCInterfaceType(CurMeth->getClassInterface());
3354 }
3355 }
3356 }
3357 }
3358 checkFoundationAPI(*this, SelLoc, Method, ArrayRef(Args, NumArgs),
3359 ReceiverType, IsClassObjectCall);
3360 }
3361
3362 if (getLangOpts().ObjCAutoRefCount) {
3363 // In ARC, annotate delegate init calls.
3364 if (Result->getMethodFamily() == OMF_init &&
3365 (SuperLoc.isValid() || isSelfExpr(Receiver))) {
3366 // Only consider init calls *directly* in init implementations,
3367 // not within blocks.
3368 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(CurContext);
3369 if (method && method->getMethodFamily() == OMF_init) {
3370 // The implicit assignment to self means we also don't want to
3371 // consume the result.
3372 Result->setDelegateInitCall(true);
3373 return Result;
3374 }
3375 }
3376
3377 // In ARC, check for message sends which are likely to introduce
3378 // retain cycles.
3380 }
3381
3382 if (getLangOpts().ObjCWeak) {
3383 if (!isImplicit && Method) {
3384 if (const ObjCPropertyDecl *Prop = Method->findPropertyDecl()) {
3385 bool IsWeak =
3386 Prop->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak;
3387 if (!IsWeak && Sel.isUnarySelector())
3388 IsWeak = ReturnType.getObjCLifetime() & Qualifiers::OCL_Weak;
3389 if (IsWeak && !isUnevaluatedContext() &&
3390 !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, LBracLoc))
3392 }
3393 }
3394 }
3395
3396 CheckObjCCircularContainer(Result);
3397
3399}
3400
3402 if (ObjCSelectorExpr *OSE =
3403 dyn_cast<ObjCSelectorExpr>(Arg->IgnoreParenCasts())) {
3404 Selector Sel = OSE->getSelector();
3405 SourceLocation Loc = OSE->getAtLoc();
3406 auto Pos = S.ReferencedSelectors.find(Sel);
3407 if (Pos != S.ReferencedSelectors.end() && Pos->second == Loc)
3408 S.ReferencedSelectors.erase(Pos);
3409 }
3410}
3411
3412// ActOnInstanceMessage - used for both unary and keyword messages.
3413// ArgExprs is optional - if it is present, the number of expressions
3414// is obtained from Sel.getNumArgs().
3416 Expr *Receiver,
3417 Selector Sel,
3418 SourceLocation LBracLoc,
3419 ArrayRef<SourceLocation> SelectorLocs,
3420 SourceLocation RBracLoc,
3421 MultiExprArg Args) {
3422 if (!Receiver)
3423 return ExprError();
3424
3425 // A ParenListExpr can show up while doing error recovery with invalid code.
3426 if (isa<ParenListExpr>(Receiver)) {
3428 if (Result.isInvalid()) return ExprError();
3429 Receiver = Result.get();
3430 }
3431
3433 IdentifierInfo *SelectorId = &Context.Idents.get("respondsToSelector");
3435 }
3436 if (Sel == RespondsToSelectorSel)
3437 RemoveSelectorFromWarningCache(*this, Args[0]);
3438
3439 return BuildInstanceMessage(Receiver, Receiver->getType(),
3440 /*SuperLoc=*/SourceLocation(), Sel,
3441 /*Method=*/nullptr, LBracLoc, SelectorLocs,
3442 RBracLoc, Args);
3443}
3444
3446 /// int, void, struct A
3448
3449 /// id, void (^)()
3451
3452 /// id*, id***, void (^*)(),
3454
3455 /// void* might be a normal C type, or it might a CF type.
3457
3458 /// struct A*
3461
3463 return (ACTC == ACTC_retainable ||
3464 ACTC == ACTC_coreFoundation ||
3465 ACTC == ACTC_voidPtr);
3466}
3467
3469 return ACTC == ACTC_none ||
3470 ACTC == ACTC_voidPtr ||
3471 ACTC == ACTC_coreFoundation;
3472}
3473
3475 bool isIndirect = false;
3476
3477 // Ignore an outermost reference type.
3478 if (const ReferenceType *ref = type->getAs<ReferenceType>()) {
3479 type = ref->getPointeeType();
3480 isIndirect = true;
3481 }
3482
3483 // Drill through pointers and arrays recursively.
3484 while (true) {
3485 if (const PointerType *ptr = type->getAs<PointerType>()) {
3486 type = ptr->getPointeeType();
3487
3488 // The first level of pointer may be the innermost pointer on a CF type.
3489 if (!isIndirect) {
3490 if (type->isVoidType()) return ACTC_voidPtr;
3491 if (type->isRecordType()) return ACTC_coreFoundation;
3492 }
3493 } else if (const ArrayType *array = type->getAsArrayTypeUnsafe()) {
3494 type = QualType(array->getElementType()->getBaseElementTypeUnsafe(), 0);
3495 } else {
3496 break;
3497 }
3498 isIndirect = true;
3499 }
3500
3501 if (isIndirect) {
3502 if (type->isObjCARCBridgableType())
3504 return ACTC_none;
3505 }
3506
3507 if (type->isObjCARCBridgableType())
3508 return ACTC_retainable;
3509
3510 return ACTC_none;
3511}
3512
3513namespace {
3514 /// A result from the cast checker.
3515 enum ACCResult {
3516 /// Cannot be casted.
3517 ACC_invalid,
3518
3519 /// Can be safely retained or not retained.
3520 ACC_bottom,
3521
3522 /// Can be casted at +0.
3523 ACC_plusZero,
3524
3525 /// Can be casted at +1.
3526 ACC_plusOne
3527 };
3528 ACCResult merge(ACCResult left, ACCResult right) {
3529 if (left == right) return left;
3530 if (left == ACC_bottom) return right;
3531 if (right == ACC_bottom) return left;
3532 return ACC_invalid;
3533 }
3534
3535 /// A checker which white-lists certain expressions whose conversion
3536 /// to or from retainable type would otherwise be forbidden in ARC.
3537 class ARCCastChecker : public StmtVisitor<ARCCastChecker, ACCResult> {
3539
3540 ASTContext &Context;
3541 ARCConversionTypeClass SourceClass;
3542 ARCConversionTypeClass TargetClass;
3543 bool Diagnose;
3544
3545 static bool isCFType(QualType type) {
3546 // Someday this can use ns_bridged. For now, it has to do this.
3547 return type->isCARCBridgableType();
3548 }
3549
3550 public:
3551 ARCCastChecker(ASTContext &Context, ARCConversionTypeClass source,
3552 ARCConversionTypeClass target, bool diagnose)
3553 : Context(Context), SourceClass(source), TargetClass(target),
3554 Diagnose(diagnose) {}
3555
3556 using super::Visit;
3557 ACCResult Visit(Expr *e) {
3558 return super::Visit(e->IgnoreParens());
3559 }
3560
3561 ACCResult VisitStmt(Stmt *s) {
3562 return ACC_invalid;
3563 }
3564
3565 /// Null pointer constants can be casted however you please.
3566 ACCResult VisitExpr(Expr *e) {
3568 return ACC_bottom;
3569 return ACC_invalid;
3570 }
3571
3572 /// Objective-C string literals can be safely casted.
3573 ACCResult VisitObjCStringLiteral(ObjCStringLiteral *e) {
3574 // If we're casting to any retainable type, go ahead. Global
3575 // strings are immune to retains, so this is bottom.
3576 if (isAnyRetainable(TargetClass)) return ACC_bottom;
3577
3578 return ACC_invalid;
3579 }
3580
3581 /// Look through certain implicit and explicit casts.
3582 ACCResult VisitCastExpr(CastExpr *e) {
3583 switch (e->getCastKind()) {
3584 case CK_NullToPointer:
3585 return ACC_bottom;
3586
3587 case CK_NoOp:
3588 case CK_LValueToRValue:
3589 case CK_BitCast:
3590 case CK_CPointerToObjCPointerCast:
3591 case CK_BlockPointerToObjCPointerCast:
3592 case CK_AnyPointerToBlockPointerCast:
3593 return Visit(e->getSubExpr());
3594
3595 default:
3596 return ACC_invalid;
3597 }
3598 }
3599
3600 /// Look through unary extension.
3601 ACCResult VisitUnaryExtension(UnaryOperator *e) {
3602 return Visit(e->getSubExpr());
3603 }
3604
3605 /// Ignore the LHS of a comma operator.
3606 ACCResult VisitBinComma(BinaryOperator *e) {
3607 return Visit(e->getRHS());
3608 }
3609
3610 /// Conditional operators are okay if both sides are okay.
3611 ACCResult VisitConditionalOperator(ConditionalOperator *e) {
3612 ACCResult left = Visit(e->getTrueExpr());
3613 if (left == ACC_invalid) return ACC_invalid;
3614 return merge(left, Visit(e->getFalseExpr()));
3615 }
3616
3617 /// Look through pseudo-objects.
3618 ACCResult VisitPseudoObjectExpr(PseudoObjectExpr *e) {
3619 // If we're getting here, we should always have a result.
3620 return Visit(e->getResultExpr());
3621 }
3622
3623 /// Statement expressions are okay if their result expression is okay.
3624 ACCResult VisitStmtExpr(StmtExpr *e) {
3625 return Visit(e->getSubStmt()->body_back());
3626 }
3627
3628 /// Some declaration references are okay.
3629 ACCResult VisitDeclRefExpr(DeclRefExpr *e) {
3630 VarDecl *var = dyn_cast<VarDecl>(e->getDecl());
3631 // References to global constants are okay.
3632 if (isAnyRetainable(TargetClass) &&
3633 isAnyRetainable(SourceClass) &&
3634 var &&
3635 !var->hasDefinition(Context) &&
3636 var->getType().isConstQualified()) {
3637
3638 // In system headers, they can also be assumed to be immune to retains.
3639 // These are things like 'kCFStringTransformToLatin'.
3640 if (Context.getSourceManager().isInSystemHeader(var->getLocation()))
3641 return ACC_bottom;
3642
3643 return ACC_plusZero;
3644 }
3645
3646 // Nothing else.
3647 return ACC_invalid;
3648 }
3649
3650 /// Some calls are okay.
3651 ACCResult VisitCallExpr(CallExpr *e) {
3652 if (FunctionDecl *fn = e->getDirectCallee())
3653 if (ACCResult result = checkCallToFunction(fn))
3654 return result;
3655
3656 return super::VisitCallExpr(e);
3657 }
3658
3659 ACCResult checkCallToFunction(FunctionDecl *fn) {
3660 // Require a CF*Ref return type.
3661 if (!isCFType(fn->getReturnType()))
3662 return ACC_invalid;
3663
3664 if (!isAnyRetainable(TargetClass))
3665 return ACC_invalid;
3666
3667 // Honor an explicit 'not retained' attribute.
3668 if (fn->hasAttr<CFReturnsNotRetainedAttr>())
3669 return ACC_plusZero;
3670
3671 // Honor an explicit 'retained' attribute, except that for
3672 // now we're not going to permit implicit handling of +1 results,
3673 // because it's a bit frightening.
3674 if (fn->hasAttr<CFReturnsRetainedAttr>())
3675 return Diagnose ? ACC_plusOne
3676 : ACC_invalid; // ACC_plusOne if we start accepting this
3677
3678 // Recognize this specific builtin function, which is used by CFSTR.
3679 unsigned builtinID = fn->getBuiltinID();
3680 if (builtinID == Builtin::BI__builtin___CFStringMakeConstantString)
3681 return ACC_bottom;
3682
3683 // Otherwise, don't do anything implicit with an unaudited function.
3684 if (!fn->hasAttr<CFAuditedTransferAttr>())
3685 return ACC_invalid;
3686
3687 // Otherwise, it's +0 unless it follows the create convention.
3689 return Diagnose ? ACC_plusOne
3690 : ACC_invalid; // ACC_plusOne if we start accepting this
3691
3692 return ACC_plusZero;
3693 }
3694
3695 ACCResult VisitObjCMessageExpr(ObjCMessageExpr *e) {
3696 return checkCallToMethod(e->getMethodDecl());
3697 }
3698
3699 ACCResult VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *e) {
3700 ObjCMethodDecl *method;
3701 if (e->isExplicitProperty())
3703 else
3704 method = e->getImplicitPropertyGetter();
3705 return checkCallToMethod(method);
3706 }
3707
3708 ACCResult checkCallToMethod(ObjCMethodDecl *method) {
3709 if (!method) return ACC_invalid;
3710
3711 // Check for message sends to functions returning CF types. We
3712 // just obey the Cocoa conventions with these, even though the
3713 // return type is CF.
3714 if (!isAnyRetainable(TargetClass) || !isCFType(method->getReturnType()))
3715 return ACC_invalid;
3716
3717 // If the method is explicitly marked not-retained, it's +0.
3718 if (method->hasAttr<CFReturnsNotRetainedAttr>())
3719 return ACC_plusZero;
3720
3721 // If the method is explicitly marked as returning retained, or its
3722 // selector follows a +1 Cocoa convention, treat it as +1.
3723 if (method->hasAttr<CFReturnsRetainedAttr>())
3724 return ACC_plusOne;
3725
3726 switch (method->getSelector().getMethodFamily()) {
3727 case OMF_alloc:
3728 case OMF_copy:
3729 case OMF_mutableCopy:
3730 case OMF_new:
3731 return ACC_plusOne;
3732
3733 default:
3734 // Otherwise, treat it as +0.
3735 return ACC_plusZero;
3736 }
3737 }
3738 };
3739} // end anonymous namespace
3740
3741bool Sema::isKnownName(StringRef name) {
3742 if (name.empty())
3743 return false;
3744 LookupResult R(*this, &Context.Idents.get(name), SourceLocation(),
3746 return LookupName(R, TUScope, false);
3747}
3748
3749template <typename DiagBuilderT>
3751 Sema &S, DiagBuilderT &DiagB, Sema::CheckedConversionKind CCK,
3752 SourceLocation afterLParen, QualType castType, Expr *castExpr,
3753 Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName) {
3754 // We handle C-style and implicit casts here.
3755 switch (CCK) {
3760 break;
3762 return;
3763 }
3764
3765 if (CFBridgeName) {
3766 if (CCK == Sema::CCK_OtherCast) {
3767 if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) {
3768 SourceRange range(NCE->getOperatorLoc(),
3769 NCE->getAngleBrackets().getEnd());
3770 SmallString<32> BridgeCall;
3771
3773 char PrevChar = *SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
3775 BridgeCall += ' ';
3776
3777 BridgeCall += CFBridgeName;
3778 DiagB.AddFixItHint(FixItHint::CreateReplacement(range, BridgeCall));
3779 }
3780 return;
3781 }
3782 Expr *castedE = castExpr;
3783 if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(castedE))
3784 castedE = CCE->getSubExpr();
3785 castedE = castedE->IgnoreImpCasts();
3786 SourceRange range = castedE->getSourceRange();
3787
3788 SmallString<32> BridgeCall;
3789
3791 char PrevChar = *SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
3793 BridgeCall += ' ';
3794
3795 BridgeCall += CFBridgeName;
3796
3797 if (isa<ParenExpr>(castedE)) {
3798 DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
3799 BridgeCall));
3800 } else {
3801 BridgeCall += '(';
3802 DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
3803 BridgeCall));
3804 DiagB.AddFixItHint(FixItHint::CreateInsertion(
3805 S.getLocForEndOfToken(range.getEnd()),
3806 ")"));
3807 }
3808 return;
3809 }
3810
3811 if (CCK == Sema::CCK_CStyleCast) {
3812 DiagB.AddFixItHint(FixItHint::CreateInsertion(afterLParen, bridgeKeyword));
3813 } else if (CCK == Sema::CCK_OtherCast) {
3814 if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) {
3815 std::string castCode = "(";
3816 castCode += bridgeKeyword;
3817 castCode += castType.getAsString();
3818 castCode += ")";
3819 SourceRange Range(NCE->getOperatorLoc(),
3820 NCE->getAngleBrackets().getEnd());
3821 DiagB.AddFixItHint(FixItHint::CreateReplacement(Range, castCode));
3822 }
3823 } else {
3824 std::string castCode = "(";
3825 castCode += bridgeKeyword;
3826 castCode += castType.getAsString();
3827 castCode += ")";
3828 Expr *castedE = castExpr->IgnoreImpCasts();
3829 SourceRange range = castedE->getSourceRange();
3830 if (isa<ParenExpr>(castedE)) {
3831 DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
3832 castCode));
3833 } else {
3834 castCode += "(";
3835 DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
3836 castCode));
3837 DiagB.AddFixItHint(FixItHint::CreateInsertion(
3838 S.getLocForEndOfToken(range.getEnd()),
3839 ")"));
3840 }
3841 }
3842}
3843
3844template <typename T>
3845static inline T *getObjCBridgeAttr(const TypedefType *TD) {
3846 TypedefNameDecl *TDNDecl = TD->getDecl();
3847 QualType QT = TDNDecl->getUnderlyingType();
3848 if (QT->isPointerType()) {
3849 QT = QT->getPointeeType();
3850 if (const RecordType *RT = QT->getAs<RecordType>()) {
3851 for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {
3852 if (auto *attr = Redecl->getAttr<T>())
3853 return attr;
3854 }
3855 }
3856 }
3857 return nullptr;
3858}
3859
3860static ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttrFromType(QualType T,
3861 TypedefNameDecl *&TDNDecl) {
3862 while (const auto *TD = T->getAs<TypedefType>()) {
3863 TDNDecl = TD->getDecl();
3864 if (ObjCBridgeRelatedAttr *ObjCBAttr =
3865 getObjCBridgeAttr<ObjCBridgeRelatedAttr>(TD))
3866 return ObjCBAttr;
3867 T = TDNDecl->getUnderlyingType();
3868 }
3869 return nullptr;
3870}
3871
3872static void
3874 QualType castType, ARCConversionTypeClass castACTC,
3875 Expr *castExpr, Expr *realCast,
3876 ARCConversionTypeClass exprACTC,
3878 SourceLocation loc =
3879 (castRange.isValid() ? castRange.getBegin() : castExpr->getExprLoc());
3880
3882 UnavailableAttr::IR_ARCForbiddenConversion))
3883 return;
3884
3885 QualType castExprType = castExpr->getType();
3886 // Defer emitting a diagnostic for bridge-related casts; that will be
3887 // handled by CheckObjCBridgeRelatedConversions.
3888 TypedefNameDecl *TDNDecl = nullptr;
3889 if ((castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable &&
3890 ObjCBridgeRelatedAttrFromType(castType, TDNDecl)) ||
3891 (exprACTC == ACTC_coreFoundation && castACTC == ACTC_retainable &&
3892 ObjCBridgeRelatedAttrFromType(castExprType, TDNDecl)))
3893 return;
3894
3895 unsigned srcKind = 0;
3896 switch (exprACTC) {
3897 case ACTC_none:
3899 case ACTC_voidPtr:
3900 srcKind = (castExprType->isPointerType() ? 1 : 0);
3901 break;
3902 case ACTC_retainable:
3903 srcKind = (castExprType->isBlockPointerType() ? 2 : 3);
3904 break;
3906 srcKind = 4;
3907 break;
3908 }
3909
3910 // Check whether this could be fixed with a bridge cast.
3911 SourceLocation afterLParen = S.getLocForEndOfToken(castRange.getBegin());
3912 SourceLocation noteLoc = afterLParen.isValid() ? afterLParen : loc;
3913
3914 unsigned convKindForDiag = Sema::isCast(CCK) ? 0 : 1;
3915
3916 // Bridge from an ARC type to a CF type.
3917 if (castACTC == ACTC_retainable && isAnyRetainable(exprACTC)) {
3918
3919 S.Diag(loc, diag::err_arc_cast_requires_bridge)
3920 << convKindForDiag
3921 << 2 // of C pointer type
3922 << castExprType
3923 << unsigned(castType->isBlockPointerType()) // to ObjC|block type
3924 << castType
3925 << castRange
3926 << castExpr->getSourceRange();
3927 bool br = S.isKnownName("CFBridgingRelease");
3928 ACCResult CreateRule =
3929 ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr);
3930 assert(CreateRule != ACC_bottom && "This cast should already be accepted.");
3931 if (CreateRule != ACC_plusOne)
3932 {
3933 auto DiagB = (CCK != Sema::CCK_OtherCast)
3934 ? S.Diag(noteLoc, diag::note_arc_bridge)
3935 : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);
3936
3937 addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
3938 castType, castExpr, realCast, "__bridge ",
3939 nullptr);
3940 }
3941 if (CreateRule != ACC_plusZero)
3942 {
3943 auto DiagB = (CCK == Sema::CCK_OtherCast && !br)
3944 ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_transfer)
3945 << castExprType
3946 : S.Diag(br ? castExpr->getExprLoc() : noteLoc,
3947 diag::note_arc_bridge_transfer)
3948 << castExprType << br;
3949
3950 addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
3951 castType, castExpr, realCast, "__bridge_transfer ",
3952 br ? "CFBridgingRelease" : nullptr);
3953 }
3954
3955 return;
3956 }
3957
3958 // Bridge from a CF type to an ARC type.
3959 if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC)) {
3960 bool br = S.isKnownName("CFBridgingRetain");
3961 S.Diag(loc, diag::err_arc_cast_requires_bridge)
3962 << convKindForDiag
3963 << unsigned(castExprType->isBlockPointerType()) // of ObjC|block type
3964 << castExprType
3965 << 2 // to C pointer type
3966 << castType
3967 << castRange
3968 << castExpr->getSourceRange();
3969 ACCResult CreateRule =
3970 ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr);
3971 assert(CreateRule != ACC_bottom && "This cast should already be accepted.");
3972 if (CreateRule != ACC_plusOne)
3973 {
3974 auto DiagB = (CCK != Sema::CCK_OtherCast)
3975 ? S.Diag(noteLoc, diag::note_arc_bridge)
3976 : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);
3977 addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
3978 castType, castExpr, realCast, "__bridge ",
3979 nullptr);
3980 }
3981 if (CreateRule != ACC_plusZero)
3982 {
3983 auto DiagB = (CCK == Sema::CCK_OtherCast && !br)
3984 ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_retained)
3985 << castType
3986 : S.Diag(br ? castExpr->getExprLoc() : noteLoc,
3987 diag::note_arc_bridge_retained)
3988 << castType << br;
3989
3990 addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
3991 castType, castExpr, realCast, "__bridge_retained ",
3992 br ? "CFBridgingRetain" : nullptr);
3993 }
3994
3995 return;
3996 }
3997
3998 S.Diag(loc, diag::err_arc_mismatched_cast)
3999 << !convKindForDiag
4000 << srcKind << castExprType << castType
4001 << castRange << castExpr->getSourceRange();
4002}
4003
4004template <typename TB>
4006 bool &HadTheAttribute, bool warn) {
4007 QualType T = castExpr->getType();
4008 HadTheAttribute = false;
4009 while (const auto *TD = T->getAs<TypedefType>()) {
4010 TypedefNameDecl *TDNDecl = TD->getDecl();
4011 if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
4012 if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
4013 HadTheAttribute = true;
4014 if (Parm->isStr("id"))
4015 return true;
4016
4017 // Check for an existing type with this name.
4020 if (S.LookupName(R, S.TUScope)) {
4022 if (Target && isa<ObjCInterfaceDecl>(Target)) {
4023 ObjCInterfaceDecl *ExprClass = cast<ObjCInterfaceDecl>(Target);
4024 if (const ObjCObjectPointerType *InterfacePointerType =
4025 castType->getAsObjCInterfacePointerType()) {
4026 ObjCInterfaceDecl *CastClass
4027 = InterfacePointerType->getObjectType()->getInterface();
4028 if ((CastClass == ExprClass) ||
4029 (CastClass && CastClass->isSuperClassOf(ExprClass)))
4030 return true;
4031 if (warn)
4032 S.Diag(castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4033 << T << Target->getName() << castType->getPointeeType();
4034 return false;
4035 } else if (castType->isObjCIdType() ||
4037 castType, ExprClass)))
4038 // ok to cast to 'id'.
4039 // casting to id<p-list> is ok if bridge type adopts all of
4040 // p-list protocols.
4041 return true;
4042 else {
4043 if (warn) {
4044 S.Diag(castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4045 << T << Target->getName() << castType;
4046 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4047 S.Diag(Target->getBeginLoc(), diag::note_declared_at);
4048 }
4049 return false;
4050 }
4051 }
4052 } else if (!castType->isObjCIdType()) {
4053 S.Diag(castExpr->getBeginLoc(),
4054 diag::err_objc_cf_bridged_not_interface)
4055 << castExpr->getType() << Parm;
4056 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4057 }
4058 return true;
4059 }
4060 return false;
4061 }
4062 T = TDNDecl->getUnderlyingType();
4063 }
4064 return true;
4065}
4066
4067template <typename TB>
4069 bool &HadTheAttribute, bool warn) {
4070 QualType T = castType;
4071 HadTheAttribute = false;
4072 while (const auto *TD = T->getAs<TypedefType>()) {
4073 TypedefNameDecl *TDNDecl = TD->getDecl();
4074 if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
4075 if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
4076 HadTheAttribute = true;
4077 if (Parm->isStr("id"))
4078 return true;
4079
4080 NamedDecl *Target = nullptr;
4081 // Check for an existing type with this name.
4084 if (S.LookupName(R, S.TUScope)) {
4085 Target = R.getFoundDecl();
4086 if (Target && isa<ObjCInterfaceDecl>(Target)) {
4087 ObjCInterfaceDecl *CastClass = cast<ObjCInterfaceDecl>(Target);
4088 if (const ObjCObjectPointerType *InterfacePointerType =
4089 castExpr->getType()->getAsObjCInterfacePointerType()) {
4090 ObjCInterfaceDecl *ExprClass
4091 = InterfacePointerType->getObjectType()->getInterface();
4092 if ((CastClass == ExprClass) ||
4093 (ExprClass && CastClass->isSuperClassOf(ExprClass)))
4094 return true;
4095 if (warn) {
4096 S.Diag(castExpr->getBeginLoc(),
4097 diag::warn_objc_invalid_bridge_to_cf)
4098 << castExpr->getType()->getPointeeType() << T;
4099 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4100 }
4101 return false;
4102 } else if (castExpr->getType()->isObjCIdType() ||
4104 castExpr->getType(), CastClass)))
4105 // ok to cast an 'id' expression to a CFtype.
4106 // ok to cast an 'id<plist>' expression to CFtype provided plist
4107 // adopts all of CFtype's ObjetiveC's class plist.
4108 return true;
4109 else {
4110 if (warn) {
4111 S.Diag(castExpr->getBeginLoc(),
4112 diag::warn_objc_invalid_bridge_to_cf)
4113 << castExpr->getType() << castType;
4114 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4115 S.Diag(Target->getBeginLoc(), diag::note_declared_at);
4116 }
4117 return false;
4118 }
4119 }
4120 }
4121 S.Diag(castExpr->getBeginLoc(),
4122 diag::err_objc_ns_bridged_invalid_cfobject)
4123 << castExpr->getType() << castType;
4124 S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4125 if (Target)
4126 S.Diag(Target->getBeginLoc(), diag::note_declared_at);
4127 return true;
4128 }
4129 return false;
4130 }
4131 T = TDNDecl->getUnderlyingType();
4132 }
4133 return true;
4134}
4135
4137 if (!getLangOpts().ObjC)
4138 return;
4139 // warn in presence of __bridge casting to or from a toll free bridge cast.
4142 if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) {
4143 bool HasObjCBridgeAttr;
4144 bool ObjCBridgeAttrWillNotWarn =
4145 CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
4146 false);
4147 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4148 return;
4149 bool HasObjCBridgeMutableAttr;
4150 bool ObjCBridgeMutableAttrWillNotWarn =
4151 CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
4152 HasObjCBridgeMutableAttr, false);
4153 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4154 return;
4155
4156 if (HasObjCBridgeAttr)
4157 CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
4158 true);
4159 else if (HasObjCBridgeMutableAttr)
4160 CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
4161 HasObjCBridgeMutableAttr, true);
4162 }
4163 else if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable) {
4164 bool HasObjCBridgeAttr;
4165 bool ObjCBridgeAttrWillNotWarn =
4166 CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
4167 false);
4168 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4169 return;
4170 bool HasObjCBridgeMutableAttr;
4171 bool ObjCBridgeMutableAttrWillNotWarn =
4172 CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
4173 HasObjCBridgeMutableAttr, false);
4174 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4175 return;
4176
4177 if (HasObjCBridgeAttr)
4178 CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
4179 true);
4180 else if (HasObjCBridgeMutableAttr)
4181 CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
4182 HasObjCBridgeMutableAttr, true);
4183 }
4184}
4185
4187 QualType SrcType = castExpr->getType();
4188 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(castExpr)) {
4189 if (PRE->isExplicitProperty()) {
4190 if (ObjCPropertyDecl *PDecl = PRE->getExplicitProperty())
4191 SrcType = PDecl->getType();
4192 }
4193 else if (PRE->isImplicitProperty()) {
4194 if (ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter())
4195 SrcType = Getter->getReturnType();
4196 }
4197 }
4198
4201 if (srcExprACTC != ACTC_retainable || castExprACTC != ACTC_coreFoundation)
4202 return;
4203 CheckObjCBridgeRelatedConversions(castExpr->getBeginLoc(), castType, SrcType,
4204 castExpr);
4205}
4206
4208 CastKind &Kind) {
4209 if (!getLangOpts().ObjC)
4210 return false;
4211 ARCConversionTypeClass exprACTC =
4214 if ((castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) ||
4215 (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable)) {
4217 Kind = (castACTC == ACTC_coreFoundation) ? CK_BitCast
4218 : CK_CPointerToObjCPointerCast;
4219 return true;
4220 }
4221 return false;
4222}
4223
4225 QualType DestType, QualType SrcType,
4226 ObjCInterfaceDecl *&RelatedClass,
4227 ObjCMethodDecl *&ClassMethod,
4228 ObjCMethodDecl *&InstanceMethod,
4229 TypedefNameDecl *&TDNDecl,
4230 bool CfToNs, bool Diagnose) {
4231 QualType T = CfToNs ? SrcType : DestType;
4232 ObjCBridgeRelatedAttr *ObjCBAttr = ObjCBridgeRelatedAttrFromType(T, TDNDecl);
4233 if (!ObjCBAttr)
4234 return false;
4235
4236 IdentifierInfo *RCId = ObjCBAttr->getRelatedClass();
4237 IdentifierInfo *CMId = ObjCBAttr->getClassMethod();
4238 IdentifierInfo *IMId = ObjCBAttr->getInstanceMethod();
4239 if (!RCId)
4240 return false;
4241 NamedDecl *Target = nullptr;
4242 // Check for an existing type with this name.
4245 if (!LookupName(R, TUScope)) {
4246 if (Diagnose) {
4247 Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId
4248 << SrcType << DestType;
4249 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4250 }
4251 return false;
4252 }
4253 Target = R.getFoundDecl();
4254 if (Target && isa<ObjCInterfaceDecl>(Target))
4255 RelatedClass = cast<ObjCInterfaceDecl>(Target);
4256 else {
4257 if (Diagnose) {
4258 Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId
4259 << SrcType << DestType;
4260 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4261 if (Target)
4262 Diag(Target->getBeginLoc(), diag::note_declared_at);
4263 }
4264 return false;
4265 }
4266
4267 // Check for an existing class method with the given selector name.
4268 if (CfToNs && CMId) {
4270 ClassMethod = RelatedClass->lookupMethod(Sel, false);
4271 if (!ClassMethod) {
4272 if (Diagnose) {
4273 Diag(Loc, diag::err_objc_bridged_related_known_method)
4274 << SrcType << DestType << Sel << false;
4275 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4276 }
4277 return false;
4278 }
4279 }
4280
4281 // Check for an existing instance method with the given selector name.
4282 if (!CfToNs && IMId) {
4284 InstanceMethod = RelatedClass->lookupMethod(Sel, true);
4285 if (!InstanceMethod) {
4286 if (Diagnose) {
4287 Diag(Loc, diag::err_objc_bridged_related_known_method)
4288 << SrcType << DestType << Sel << true;
4289 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4290 }
4291 return false;
4292 }
4293 }
4294 return true;
4295}
4296
4297bool
4299 QualType DestType, QualType SrcType,
4300 Expr *&SrcExpr, bool Diagnose) {
4303 bool CfToNs = (rhsExprACTC == ACTC_coreFoundation && lhsExprACTC == ACTC_retainable);
4304 bool NsToCf = (rhsExprACTC == ACTC_retainable && lhsExprACTC == ACTC_coreFoundation);
4305 if (!CfToNs && !NsToCf)
4306 return false;
4307
4308 ObjCInterfaceDecl *RelatedClass;
4309 ObjCMethodDecl *ClassMethod = nullptr;
4310 ObjCMethodDecl *InstanceMethod = nullptr;
4311 TypedefNameDecl *TDNDecl = nullptr;
4312 if (!checkObjCBridgeRelatedComponents(Loc, DestType, SrcType, RelatedClass,
4313 ClassMethod, InstanceMethod, TDNDecl,
4314 CfToNs, Diagnose))
4315 return false;
4316
4317 if (CfToNs) {
4318 // Implicit conversion from CF to ObjC object is needed.
4319 if (ClassMethod) {
4320 if (Diagnose) {
4321 std::string ExpressionString = "[";
4322 ExpressionString += RelatedClass->getNameAsString();
4323 ExpressionString += " ";
4324 ExpressionString += ClassMethod->getSelector().getAsString();
4325 SourceLocation SrcExprEndLoc =
4326 getLocForEndOfToken(SrcExpr->getEndLoc());
4327 // Provide a fixit: [RelatedClass ClassMethod SrcExpr]
4328 Diag(Loc, diag::err_objc_bridged_related_known_method)
4329 << SrcType << DestType << ClassMethod->getSelector() << false
4331 ExpressionString)
4332 << FixItHint::CreateInsertion(SrcExprEndLoc, "]");
4333 Diag(RelatedClass->getBeginLoc(), diag::note_declared_at);
4334 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4335
4336 QualType receiverType = Context.getObjCInterfaceType(RelatedClass);
4337 // Argument.
4338 Expr *args[] = { SrcExpr };
4339 ExprResult msg = BuildClassMessageImplicit(receiverType, false,
4340 ClassMethod->getLocation(),
4341 ClassMethod->getSelector(), ClassMethod,
4342 MultiExprArg(args, 1));
4343 SrcExpr = msg.get();
4344 }
4345 return true;
4346 }
4347 }
4348 else {
4349 // Implicit conversion from ObjC type to CF object is needed.
4350 if (InstanceMethod) {
4351 if (Diagnose) {
4352 std::string ExpressionString;
4353 SourceLocation SrcExprEndLoc =
4354 getLocForEndOfToken(SrcExpr->getEndLoc());
4355 if (InstanceMethod->isPropertyAccessor())
4356 if (const ObjCPropertyDecl *PDecl =
4357 InstanceMethod->findPropertyDecl()) {
4358 // fixit: ObjectExpr.propertyname when it is aproperty accessor.
4359 ExpressionString = ".";
4360 ExpressionString += PDecl->getNameAsString();
4361 Diag(Loc, diag::err_objc_bridged_related_known_method)
4362 << SrcType << DestType << InstanceMethod->getSelector() << true
4363 << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
4364 }
4365 if (ExpressionString.empty()) {
4366 // Provide a fixit: [ObjectExpr InstanceMethod]
4367 ExpressionString = " ";
4368 ExpressionString += InstanceMethod->getSelector().getAsString();
4369 ExpressionString += "]";
4370
4371 Diag(Loc, diag::err_objc_bridged_related_known_method)
4372 << SrcType << DestType << InstanceMethod->getSelector() << true
4373 << FixItHint::CreateInsertion(SrcExpr->getBeginLoc(), "[")
4374 << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
4375 }
4376 Diag(RelatedClass->getBeginLoc(), diag::note_declared_at);
4377 Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);
4378
4380 SrcExpr, SrcType, InstanceMethod->getLocation(),
4381 InstanceMethod->getSelector(), InstanceMethod, std::nullopt);
4382 SrcExpr = msg.get();
4383 }
4384 return true;
4385 }
4386 }
4387 return false;
4388}
4389
4393 bool Diagnose, bool DiagnoseCFAudited,
4394 BinaryOperatorKind Opc) {
4395 QualType castExprType = castExpr->getType();
4396
4397 // For the purposes of the classification, we assume reference types
4398 // will bind to temporaries.
4399 QualType effCastType = castType;
4400 if (const ReferenceType *ref = castType->getAs<ReferenceType>())
4401 effCastType = ref->getPointeeType();
4402
4405 if (exprACTC == castACTC) {
4406 // Check for viability and report error if casting an rvalue to a
4407 // life-time qualifier.
4408 if (castACTC == ACTC_retainable &&
4409 (CCK == CCK_CStyleCast || CCK == CCK_OtherCast) &&
4410 castType != castExprType) {
4411 const Type *DT = castType.getTypePtr();
4412 QualType QDT = castType;
4413 // We desugar some types but not others. We ignore those
4414 // that cannot happen in a cast; i.e. auto, and those which
4415 // should not be de-sugared; i.e typedef.
4416 if (const ParenType *PT = dyn_cast<ParenType>(DT))
4417 QDT = PT->desugar();
4418 else if (const TypeOfType *TP = dyn_cast<TypeOfType>(DT))
4419 QDT = TP->desugar();
4420 else if (const AttributedType *AT = dyn_cast<AttributedType>(DT))
4421 QDT = AT->desugar();
4422 if (QDT != castType &&
4424 if (Diagnose) {
4425 SourceLocation loc = (castRange.isValid() ? castRange.getBegin()
4426 : castExpr->getExprLoc());
4427 Diag(loc, diag::err_arc_nolifetime_behavior);
4428 }
4429 return ACR_error;
4430 }
4431 }
4432 return ACR_okay;
4433 }
4434
4435 // The life-time qualifier cast check above is all we need for ObjCWeak.
4436 // ObjCAutoRefCount has more restrictions on what is legal.
4437 if (!getLangOpts().ObjCAutoRefCount)
4438 return ACR_okay;
4439
4440 if (isAnyCLike(exprACTC) && isAnyCLike(castACTC)) return ACR_okay;
4441
4442 // Allow all of these types to be cast to integer types (but not
4443 // vice-versa).
4444 if (castACTC == ACTC_none && castType->isIntegralType(Context))
4445 return ACR_okay;
4446
4447 // Allow casts between pointers to lifetime types (e.g., __strong id*)
4448 // and pointers to void (e.g., cv void *). Casting from void* to lifetime*
4449 // must be explicit.
4450 // Allow conversions between pointers to lifetime types and coreFoundation
4451 // pointers too, but only when the conversions are explicit.
4452 if (exprACTC == ACTC_indirectRetainable &&
4453 (castACTC == ACTC_voidPtr ||
4454 (castACTC == ACTC_coreFoundation && isCast(CCK))))
4455 return ACR_okay;
4456 if (castACTC == ACTC_indirectRetainable &&
4457 (exprACTC == ACTC_voidPtr || exprACTC == ACTC_coreFoundation) &&
4458 isCast(CCK))
4459 return ACR_okay;
4460
4461 switch (ARCCastChecker(Context, exprACTC, castACTC, false).Visit(castExpr)) {
4462 // For invalid casts, fall through.
4463 case ACC_invalid:
4464 break;
4465
4466 // Do nothing for both bottom and +0.
4467 case ACC_bottom:
4468 case ACC_plusZero:
4469 return ACR_okay;
4470
4471 // If the result is +1, consume it here.
4472 case ACC_plusOne:
4474 CK_ARCConsumeObject, castExpr, nullptr,
4477 return ACR_okay;
4478 }
4479
4480 // If this is a non-implicit cast from id or block type to a
4481 // CoreFoundation type, delay complaining in case the cast is used
4482 // in an acceptable context.
4483 if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC) && isCast(CCK))
4484 return ACR_unbridged;
4485
4486 // Issue a diagnostic about a missing @-sign when implicit casting a cstring
4487 // to 'NSString *', instead of falling through to report a "bridge cast"
4488 // diagnostic.
4489 if (castACTC == ACTC_retainable && exprACTC == ACTC_none &&
4491 return ACR_error;
4492
4493 // Do not issue "bridge cast" diagnostic when implicit casting
4494 // a retainable object to a CF type parameter belonging to an audited
4495 // CF API function. Let caller issue a normal type mismatched diagnostic
4496 // instead.
4497 if ((!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
4498 castACTC != ACTC_coreFoundation) &&
4499 !(exprACTC == ACTC_voidPtr && castACTC == ACTC_retainable &&
4500 (Opc == BO_NE || Opc == BO_EQ))) {
4501 if (Diagnose)
4502 diagnoseObjCARCConversion(*this, castRange, castType, castACTC, castExpr,
4503 castExpr, exprACTC, CCK);
4504 return ACR_error;
4505 }
4506 return ACR_okay;
4507}
4508
4509/// Given that we saw an expression with the ARCUnbridgedCastTy
4510/// placeholder type, complain bitterly.
4512 // We expect the spurious ImplicitCastExpr to already have been stripped.
4513 assert(!e->hasPlaceholderType(BuiltinType::ARCUnbridgedCast));
4514 CastExpr *realCast = cast<CastExpr>(e->IgnoreParens());
4515
4516 SourceRange castRange;
4517 QualType castType;
4519
4520 if (CStyleCastExpr *cast = dyn_cast<CStyleCastExpr>(realCast)) {
4521 castRange = SourceRange(cast->getLParenLoc(), cast->getRParenLoc());
4522 castType = cast->getTypeAsWritten();
4523 CCK = CCK_CStyleCast;
4524 } else if (ExplicitCastExpr *cast = dyn_cast<ExplicitCastExpr>(realCast)) {
4525 castRange = cast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange();
4526 castType = cast->getTypeAsWritten();
4527 CCK = CCK_OtherCast;
4528 } else {
4529 llvm_unreachable("Unexpected ImplicitCastExpr");
4530 }
4531
4532 ARCConversionTypeClass castACTC =
4534
4535 Expr *castExpr = realCast->getSubExpr();
4537
4538 diagnoseObjCARCConversion(*this, castRange, castType, castACTC,
4539 castExpr, realCast, ACTC_retainable, CCK);
4540}
4541
4542/// stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast
4543/// type, remove the placeholder cast.
4545 assert(e->hasPlaceholderType(BuiltinType::ARCUnbridgedCast));
4546
4547 if (ParenExpr *pe = dyn_cast<ParenExpr>(e)) {
4548 Expr *sub = stripARCUnbridgedCast(pe->getSubExpr());
4549 return new (Context) ParenExpr(pe->getLParen(), pe->getRParen(), sub);
4550 } else if (UnaryOperator *uo = dyn_cast<UnaryOperator>(e)) {
4551 assert(uo->getOpcode() == UO_Extension);
4552 Expr *sub = stripARCUnbridgedCast(uo->getSubExpr());
4553 return UnaryOperator::Create(Context, sub, UO_Extension, sub->getType(),
4554 sub->getValueKind(), sub->getObjectKind(),
4555 uo->getOperatorLoc(), false,
4557 } else if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {
4558 assert(!gse->isResultDependent());
4559 assert(!gse->isTypePredicate());
4560
4561 unsigned n = gse->getNumAssocs();
4562 SmallVector<Expr *, 4> subExprs;
4564 subExprs.reserve(n);
4565 subTypes.reserve(n);
4566 for (const GenericSelectionExpr::Association assoc : gse->associations()) {
4567 subTypes.push_back(assoc.getTypeSourceInfo());
4568 Expr *sub = assoc.getAssociationExpr();
4569 if (assoc.isSelected())
4570 sub = stripARCUnbridgedCast(sub);
4571 subExprs.push_back(sub);
4572 }
4573
4575 Context, gse->getGenericLoc(), gse->getControllingExpr(), subTypes,
4576 subExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
4577 gse->containsUnexpandedParameterPack(), gse->getResultIndex());
4578 } else {
4579 assert(isa<ImplicitCastExpr>(e) && "bad form of unbridged cast!");
4580 return cast<ImplicitCastExpr>(e)->getSubExpr();
4581 }
4582}
4583
4585 QualType exprType) {
4586 QualType canCastType =
4588 QualType canExprType =
4590 if (isa<ObjCObjectPointerType>(canCastType) &&
4591 castType.getObjCLifetime() == Qualifiers::OCL_Weak &&
4592 canExprType->isObjCObjectPointerType()) {
4593 if (const ObjCObjectPointerType *ObjT =
4594 canExprType->getAs<ObjCObjectPointerType>())
4595 if (const ObjCInterfaceDecl *ObjI = ObjT->getInterfaceDecl())
4596 return !ObjI->isArcWeakrefUnavailable();
4597 }
4598 return true;
4599}
4600
4601/// Look for an ObjCReclaimReturnedObject cast and destroy it.
4603 Expr *curExpr = e, *prevExpr = nullptr;
4604
4605 // Walk down the expression until we hit an implicit cast of kind
4606 // ARCReclaimReturnedObject or an Expr that is neither a Paren nor a Cast.
4607 while (true) {
4608 if (auto *pe = dyn_cast<ParenExpr>(curExpr)) {
4609 prevExpr = curExpr;
4610 curExpr = pe->getSubExpr();
4611 continue;
4612 }
4613
4614 if (auto *ce = dyn_cast<CastExpr>(curExpr)) {
4615 if (auto *ice = dyn_cast<ImplicitCastExpr>(ce))
4616 if (ice->getCastKind() == CK_ARCReclaimReturnedObject) {
4617 if (!prevExpr)
4618 return ice->getSubExpr();
4619 if (auto *pe = dyn_cast<ParenExpr>(prevExpr))
4620 pe->setSubExpr(ice->getSubExpr());
4621 else
4622 cast<CastExpr>(prevExpr)->setSubExpr(ice->getSubExpr());
4623 return e;
4624 }
4625
4626 prevExpr = curExpr;
4627 curExpr = ce->getSubExpr();
4628 continue;
4629 }
4630
4631 // Break out of the loop if curExpr is neither a Paren nor a Cast.
4632 break;
4633 }
4634
4635 return e;
4636}
4637
4639 ObjCBridgeCastKind Kind,
4640 SourceLocation BridgeKeywordLoc,
4641 TypeSourceInfo *TSInfo,
4642 Expr *SubExpr) {
4643 ExprResult SubResult = UsualUnaryConversions(SubExpr);
4644 if (SubResult.isInvalid()) return ExprError();
4645 SubExpr = SubResult.get();
4646
4647 QualType T = TSInfo->getType();
4648 QualType FromType = SubExpr->getType();
4649
4650 CastKind CK;
4651
4652 bool MustConsume = false;
4653 if (T->isDependentType() || SubExpr->isTypeDependent()) {
4654 // Okay: we'll build a dependent expression type.
4655 CK = CK_Dependent;
4656 } else if (T->isObjCARCBridgableType() && FromType->isCARCBridgableType()) {
4657 // Casting CF -> id
4658 CK = (T->isBlockPointerType() ? CK_AnyPointerToBlockPointerCast
4659 : CK_CPointerToObjCPointerCast);
4660 switch (Kind) {
4661 case OBC_Bridge:
4662 break;
4663
4664 case OBC_BridgeRetained: {
4665 bool br = isKnownName("CFBridgingRelease");
4666 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4667 << 2
4668 << FromType
4669 << (T->isBlockPointerType()? 1 : 0)
4670 << T
4671 << SubExpr->getSourceRange()
4672 << Kind;
4673 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4674 << FixItHint::CreateReplacement(BridgeKeywordLoc, "__bridge");
4675 Diag(BridgeKeywordLoc, diag::note_arc_bridge_transfer)
4676 << FromType << br
4677 << FixItHint::CreateReplacement(BridgeKeywordLoc,
4678 br ? "CFBridgingRelease "
4679 : "__bridge_transfer ");
4680
4681 Kind = OBC_Bridge;
4682 break;
4683 }
4684
4685 case OBC_BridgeTransfer:
4686 // We must consume the Objective-C object produced by the cast.
4687 MustConsume = true;
4688 break;
4689 }
4690 } else if (T->isCARCBridgableType() && FromType->isObjCARCBridgableType()) {
4691 // Okay: id -> CF
4692 CK = CK_BitCast;
4693 switch (Kind) {
4694 case OBC_Bridge:
4695 // Reclaiming a value that's going to be __bridge-casted to CF
4696 // is very dangerous, so we don't do it.
4697 SubExpr = maybeUndoReclaimObject(SubExpr);
4698 break;
4699
4700 case OBC_BridgeRetained:
4701 // Produce the object before casting it.
4702 SubExpr = ImplicitCastExpr::Create(Context, FromType, CK_ARCProduceObject,
4703 SubExpr, nullptr, VK_PRValue,
4705 break;
4706
4707 case OBC_BridgeTransfer: {
4708 bool br = isKnownName("CFBridgingRetain");
4709 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4710 << (FromType->isBlockPointerType()? 1 : 0)
4711 << FromType
4712 << 2
4713 << T
4714 << SubExpr->getSourceRange()
4715 << Kind;
4716
4717 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4718 << FixItHint::CreateReplacement(BridgeKeywordLoc, "__bridge ");
4719 Diag(BridgeKeywordLoc, diag::note_arc_bridge_retained)
4720 << T << br
4721 << FixItHint::CreateReplacement(BridgeKeywordLoc,
4722 br ? "CFBridgingRetain " : "__bridge_retained");
4723
4724 Kind = OBC_Bridge;
4725 break;
4726 }
4727 }
4728 } else {
4729 Diag(LParenLoc, diag::err_arc_bridge_cast_incompatible)
4730 << FromType << T << Kind
4731 << SubExpr->getSourceRange()
4732 << TSInfo->getTypeLoc().getSourceRange();
4733 return ExprError();
4734 }
4735
4736 Expr *Result = new (Context) ObjCBridgedCastExpr(LParenLoc, Kind, CK,
4737 BridgeKeywordLoc,
4738 TSInfo, SubExpr);
4739
4740 if (MustConsume) {
4742 Result = ImplicitCastExpr::Create(Context, T, CK_ARCConsumeObject, Result,
4743 nullptr, VK_PRValue, FPOptionsOverride());
4744 }
4745
4746 return Result;
4747}
4748
4750 SourceLocation LParenLoc,
4751 ObjCBridgeCastKind Kind,
4752 SourceLocation BridgeKeywordLoc,
4754 SourceLocation RParenLoc,
4755 Expr *SubExpr) {
4756 TypeSourceInfo *TSInfo = nullptr;
4757 QualType T = GetTypeFromParser(Type, &TSInfo);
4758 if (Kind == OBC_Bridge)
4759 CheckTollFreeBridgeCast(T, SubExpr);
4760 if (!TSInfo)
4761 TSInfo = Context.getTrivialTypeSourceInfo(T, LParenLoc);
4762 return BuildObjCBridgedCast(LParenLoc, Kind, BridgeKeywordLoc, TSInfo,
4763 SubExpr);
4764}
Defines the clang::ASTContext interface.
StringRef P
static StringRef bytes(const std::vector< T, Allocator > &v)
Definition: ASTWriter.cpp:123
#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:40
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, Sema::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 void addFixitForObjCARCConversion(Sema &S, DiagBuilderT &DiagB, Sema::CheckedConversionKind CCK, SourceLocation afterLParen, QualType castType, Expr *castExpr, Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName)
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 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:700
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1068
const ConstantArrayType * getAsConstantArrayType(QualType T) const
Definition: ASTContext.h:2742
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:2549
void setObjCNSStringType(QualType T)
Definition: ASTContext.h:1843
CanQualType Char16Ty
Definition: ASTContext.h:1093
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
CanQualType VoidPtrTy
Definition: ASTContext.h:1113
CanQualType DependentTy
Definition: ASTContext.h:1114
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:1575
IdentifierTable & Idents
Definition: ASTContext.h:639
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:640
QualType getObjCInstanceType()
Retrieve the Objective-C "instancetype" type, if already known; otherwise, returns a NULL type;.
Definition: ASTContext.h:1929
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
Definition: ASTContext.h:2094
CanQualType ObjCBuiltinIdTy
Definition: ASTContext.h:1117
CanQualType BoolTy
Definition: ASTContext.h:1087
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
Definition: ASTContext.h:2058
CanQualType UnsignedLongTy
Definition: ASTContext.h:1096
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:1088
CanQualType PseudoObjectTy
Definition: ASTContext.h:1116
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:2295
QualType getObjCIdType() const
Represents the Objective-CC id type.
Definition: ASTContext.h:2048
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Definition: ASTContext.h:2592
CanQualType UnknownAnyTy
Definition: ASTContext.h:1114
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:1835
CanQualType Char32Ty
Definition: ASTContext.h:1094
QualType getObjCNSStringType() const
Definition: ASTContext.h:1839
QualType getWideCharType() const
Return the type of wide characters.
Definition: ASTContext.h:1778
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:3147
ArraySizeModifier getSizeModifier() const
Definition: Type.h:3161
QualType getElementType() const
Definition: Type.h:3159
unsigned getIndexTypeCVRQualifiers() const
Definition: Type.h:3169
An attributed type is a type to which a type attribute has been applied.
Definition: Type.h:5147
static Kind getNullabilityAttrKind(NullabilityKind kind)
Retrieve the attribute kind corresponding to the given nullability kind.
Definition: Type.h:5202
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:4673
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3834
Expr * getRHS() const
Definition: Expr.h:3885
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Definition: Expr.h:3765
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:2819
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition: Expr.h:2989
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:3489
CastKind getCastKind() const
Definition: Expr.h:3533
Expr * getSubExpr()
Definition: Expr.h:3539
void setExprNeedsCleanups(bool SideEffects)
Definition: CleanupInfo.h:28
Stmt * body_back()
Definition: Stmt.h:1667
ConditionalOperator - The ?: ternary operator.
Definition: Expr.h:4173
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Definition: Expr.h:4205
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Definition: Expr.h:4200
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3186
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:1446
Decl * getNonClosureAncestor()
Find the nearest non-closure ancestor of this context, i.e.
Definition: DeclBase.cpp:1178
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:598
bool isInvalidDecl() const
Definition: DeclBase.h:593
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
Definition: DeclBase.h:564
SourceLocation getLocation() const
Definition: DeclBase.h:444
DeclContext * getDeclContext()
Definition: DeclBase.h:453
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclBase.h:436
bool hasAttr() const
Definition: DeclBase.h:582
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:5118
ExplicitCastExpr - An explicit cast written in the source code.
Definition: Expr.h:3724
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:3072
@ 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:3050
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:3062
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:3045
bool isObjCSelfExpr() const
Check if this expression is the ObjC 'self' implicit parameter.
Definition: Expr.cpp:4047
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3041
@ 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:3025
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:3904
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:870
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:1959
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition: Decl.cpp:3597
QualType getReturnType() const
Definition: Decl.h:2722
Represents a C11 generic selection.
Definition: Expr.h:5719
AssociationTy< false > Association
Definition: Expr.h:5950
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:4456
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:2060
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:577
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:563
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:2542
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:944
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
Definition: DeclObjC.cpp:92
ObjCPropertyDecl * FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyDeclaration - Finds declaration of the property given its name in 'PropertyId' and return...
Definition: DeclObjC.cpp:249
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:1150
ObjCMethodDecl * lookupClassMethod(Selector Sel) const
Lookup a class method for a given selector.
Definition: DeclObjC.h:1847
static ObjCInterfaceDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, ObjCTypeParamList *typeParamList, ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc=SourceLocation(), bool isInternal=false)
Definition: DeclObjC.cpp:1542
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
Definition: DeclObjC.cpp:638
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
Definition: DeclObjC.h:1842
ObjCMethodDecl * lookupPrivateClassMethod(const Selector &Sel)
Definition: DeclObjC.h:1857
ObjCMethodDecl * getCategoryClassMethod(Selector Sel) const
Definition: DeclObjC.cpp:1781
ObjCMethodDecl * lookupPrivateMethod(const Selector &Sel, bool Instance=true) const
Lookup a method in the classes implementation hierarchy.
Definition: DeclObjC.cpp:757
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:700
ObjCInterfaceDecl * getSuperClass() const
Definition: DeclObjC.cpp:351
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:1805
Interfaces are the core concept in Objective-C for object oriented design.
Definition: Type.h:6495
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
Definition: Type.cpp:849
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1947
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:945
static ObjCMessageExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, QualType SuperType, Selector Sel, ArrayRef< SourceLocation > SelLocs, ObjCMethodDecl *Method, ArrayRef< Expr * > Args, SourceLocation RBracLoc, bool isImplicit)
Create a message send to super.
Definition: ExprObjC.cpp:175
Selector getSelector() const
Definition: ExprObjC.cpp:293
const ObjCMethodDecl * getMethodDecl() const
Definition: ExprObjC.h:1356
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
bool isDesignatedInitializerForTheInterface(const ObjCMethodDecl **InitMethod=nullptr) const
Returns true if the method selector resolves to a designated initializer in the class's interface.
Definition: DeclObjC.cpp:889
ImplicitParamDecl * getSelfDecl() const
Definition: DeclObjC.h:418
ArrayRef< ParmVarDecl * > parameters() const
Definition: DeclObjC.h:373
unsigned param_size() const
Definition: DeclObjC.h:347
bool isPropertyAccessor() const
Definition: DeclObjC.h:436
void getOverriddenMethods(SmallVectorImpl< const ObjCMethodDecl * > &Overridden) const
Return overridden methods for the given Method.
Definition: DeclObjC.cpp:1360
static ObjCMethodDecl * Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl, bool isInstance=true, bool isVariadic=false, bool isPropertyAccessor=false, bool isSynthesizedAccessorStub=false, bool isImplicitlyDeclared=false, bool isDefined=false, ObjCImplementationControl impControl=ObjCImplementationControl::None, bool HasRelatedResultType=false)
Definition: DeclObjC.cpp:853
const ObjCPropertyDecl * findPropertyDecl(bool CheckOverrides=true) const
Returns the property associated with this method's selector.
Definition: DeclObjC.cpp:1378
QualType getSendResultType() const
Determine the type of an expression that sends a message to this function.
Definition: DeclObjC.cpp:1238
bool isVariadic() const
Definition: DeclObjC.h:431
bool hasRelatedResultType() const
Determine whether this method has a result type that is related to the message receiver's type.
Definition: DeclObjC.h:256
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclObjC.h:282
void setMethodParams(ASTContext &C, ArrayRef< ParmVarDecl * > Params, ArrayRef< SourceLocation > SelLocs=std::nullopt)
Sets the method's parameters and selector source locations.
Definition: DeclObjC.cpp:944
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Definition: DeclObjC.cpp:871
Selector getSelector() const
Definition: DeclObjC.h:327
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclObjC.h:284
bool isInstanceMethod() const
Definition: DeclObjC.h:426
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
Definition: DeclObjC.cpp:1053
QualType getReturnType() const
Definition: DeclObjC.h:329
ObjCImplementationControl getImplementationControl() const
Definition: DeclObjC.h:500
bool isClassMethod() const
Definition: DeclObjC.h:434
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.cpp:1211
Represents a pointer to an Objective C object.
Definition: Type.h:6551
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
Definition: Type.h:6563
ObjCInterfaceDecl * getInterfaceDecl() const
If this pointer points to an Objective @interface type, gets the declaration for that interface.
Definition: Type.h:6603
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
Definition: Type.cpp:1736
qual_range quals() const
Definition: Type.h:6670
Represents a class type in Objective C.
Definition: Type.h:6297
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Definition: Type.h:6530
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:729
ObjCMethodDecl * getGetterMethodDecl() const
Definition: DeclObjC.h:897
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:1967
ObjCProtocolExpr used for protocol expression in Objective-C.
Definition: ExprObjC.h:505
qual_range quals() const
Definition: Type.h:6195
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:2129
Sugar for parentheses used when specifying types.
Definition: Type.h:2872
Represents a parameter to a function.
Definition: Decl.h:1749
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, 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:2898
QualType getPointeeType() const
Definition: Type.h:2908
IdentifierTable & getIdentifierTable()
SelectorTable & getSelectorTable()
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:6299
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
Definition: Expr.h:6352
A (possibly-)qualified type.
Definition: Type.h:737
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
Definition: Type.cpp:2665
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
Definition: Type.h:1088
QualType withConst() const
Definition: Type.h:951
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:804
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6902
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
Definition: Type.h:1229
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:7102
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:6974
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:1544
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:1124
@ OCL_None
There is no lifetime qualification on this type.
Definition: Type.h:164
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition: Type.h:178
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5092
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3009
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 getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
Selector getNullarySelector(IdentifierInfo *ID)
Selector getUnarySelector(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
llvm::DenseMap< Selector, Lists >::iterator iterator
Definition: Sema.h:12056
iterator find(Selector Sel)
Definition: Sema.h:12059
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:426
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:6768
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:12051
void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr)
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val)
Definition: SemaExpr.cpp:3859
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition: Sema.h:7607
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:417
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:2148
bool CheckObjCBridgeRelatedConversions(SourceLocation Loc, QualType DestType, QualType SrcType, Expr *&SrcExpr, bool Diagnose=true)
bool isSelfExpr(Expr *RExpr)
Private Helper predicate to check for 'self'.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: Sema.cpp:1911
ObjCMethodDecl * ArrayWithObjectsMethod
The declaration of the arrayWithObjects:count: method.
Definition: Sema.h:12454
ObjCMethodDecl * StringWithUTF8StringMethod
The declaration of the stringWithUTF8String: method.
Definition: Sema.h:12445
bool FormatStringHasSArg(const StringLiteral *FExpr)
ObjCInterfaceDecl * NSDictionaryDecl
The declaration of the Objective-C NSDictionary class.
Definition: Sema.h:12457
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:12421
ObjCMethodDecl * LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupInstanceMethodInGlobalPool - Returns the method and warns if there are multiple signatures.
Definition: Sema.h:12684
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:1556
QualType NSNumberPointer
Pointer to NSNumber type (NSNumber *).
Definition: Sema.h:12430
ObjCMethodDecl * LookupMethodInQualifiedType(Selector Sel, const ObjCObjectPointerType *OPT, bool IsInstance)
LookupMethodInQualifiedType - Lookups up a method in protocol qualifier list of a qualified objective...
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:789
ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl)
DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but will create a trap if the resul...
Definition: SemaExpr.cpp:1039
ASTContext & Context
Definition: Sema.h:1030
ARCConversionResult
Definition: Sema.h:12636
@ ACR_error
Definition: Sema.h:12636
@ ACR_unbridged
Definition: Sema.h:12636
@ ACR_okay
Definition: Sema.h:12636
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:8678
ObjCInterfaceDecl * NSStringDecl
The declaration of the Objective-C NSString class.
Definition: Sema.h:12439
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
Definition: SemaExpr.cpp:755
ASTContext & getASTContext() const
Definition: Sema.h:501
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=NotForRedeclaration)
Look up a name, looking for a single declaration.
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:19722
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 DefaultArgumentPromotion(Expr *E)
DefaultArgumentPromotion (C99 6.5.2.2p6).
Definition: SemaExpr.cpp:872
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:1494
QualType NSValuePointer
Pointer to NSValue type (NSValue *).
Definition: Sema.h:12433
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
Definition: Sema.cpp:58
void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr)
ObjCMethodDecl * ValueWithBytesObjCTypeMethod
The declaration of the valueWithBytes:objCType: method.
Definition: Sema.h:12448
const LangOptions & getLangOpts() const
Definition: Sema.h:494
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:1029
ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind)
ActOnCXXBoolLiteral - Parse {true,false} literals.
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CCK_ImplicitConversion)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
Definition: Sema.cpp:636
ObjCMethodDecl * NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods]
The Objective-C NSNumber methods used to create NSNumber literals.
Definition: Sema.h:12436
const LangOptions & LangOpts
Definition: Sema.h:1028
ObjCMethodDecl * LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupFactoryMethodInGlobalPool - Returns the method and warns if there are multiple signatures.
Definition: Sema.h:12693
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:5938
@ LK_Boxed
Definition: Sema.h:5942
@ LK_Dictionary
Definition: Sema.h:5940
@ LK_String
Definition: Sema.h:5943
@ LK_Array
Definition: Sema.h:5939
@ LK_Numeric
Definition: Sema.h:5941
@ LK_None
Definition: Sema.h:5945
@ LK_Block
Definition: Sema.h:5944
ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, TypeSourceInfo *EncodedTypeInfo, SourceLocation RParenLoc)
ObjCInterfaceDecl * NSNumberDecl
The declaration of the Objective-C NSNumber class.
Definition: Sema.h:12424
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:5371
const ObjCMethodDecl * SelectorsForTypoCorrection(Selector Sel, QualType ObjectType=QualType())
QualType NSStringPointer
Pointer to NSString type (NSString *).
Definition: Sema.h:12442
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:1064
ExprResult ActOnClassMessage(Scope *S, ParsedType Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
ExprResult DefaultLvalueConversion(Expr *E)
Definition: SemaExpr.cpp:645
ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S)
Selector RespondsToSelectorSel
will hold 'respondsToSelector:'
Definition: Sema.h:12466
void maybeExtendBlockObject(ExprResult &E)
Do an explicit extend of the given block pointer if we're in ARC.
Definition: SemaExpr.cpp:8006
static bool isCast(CheckedConversionKind CCK)
Definition: Sema.h:1930
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:1163
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:12463
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
Definition: Sema.h:6505
DeclContext * getFunctionLevelDeclContext(bool AllowLambda=false) const
If AllowLambda is true, treat lambda as function.
Definition: Sema.cpp:1469
@ MMS_loose
Definition: Sema.h:12094
ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=NotForRedeclaration)
Find the protocol with the given name, if any.
bool isKnownName(StringRef name)
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
Definition: SemaExpr.cpp:21731
CheckedConversionKind
The kind of conversion being performed.
Definition: Sema.h:890
@ CCK_OtherCast
A cast other than a C-style cast.
Definition: Sema.h:898
@ CCK_ForBuiltinOverloadedOp
A conversion for an operand of a builtin overloaded operator.
Definition: Sema.h:900
@ CCK_CStyleCast
A C-style cast.
Definition: Sema.h:894
@ CCK_ImplicitConversion
An implicit conversion.
Definition: Sema.h:892
@ CCK_FunctionalCast
A functional-style cast.
Definition: Sema.h:896
GlobalMethodPool MethodPool
Method Pool - allows efficient lookup when typechecking messages to "id".
Definition: Sema.h:12076
SourceManager & getSourceManager() const
Definition: Sema.h:499
bool makeUnavailableInSystemHeader(SourceLocation loc, UnavailableAttr::ImplicitReason reason)
makeUnavailableInSystemHeader - There is an error in the current context.
Definition: Sema.cpp:520
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:12451
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:21904
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:224
ObjCInterfaceDecl * getObjCInterfaceDecl(IdentifierInfo *&Id, SourceLocation IdLoc, bool TypoCorrection=false)
Look for an Objective-C class in the translation unit.
Definition: SemaDecl.cpp:2310
@ CTK_ErrorRecovery
Definition: Sema.h:7859
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:9249
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
Definition: Sema.h:1002
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:21659
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:1033
void checkRetainCycles(ObjCMessageExpr *msg)
checkRetainCycles - Check whether an Objective-C message send might create an obvious retain cycle.
DiagnosticsEngine & Diags
Definition: Sema.h:1032
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
Definition: SemaInit.cpp:10642
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:17589
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:12538
@ ObjCSuperMessage
The message is sent to 'super'.
Definition: Sema.h:12540
@ ObjCClassMessage
The message is a class message, and the identifier is a type name.
Definition: Sema.h:12545
@ ObjCInstanceMessage
The message is an instance message.
Definition: Sema.h:12542
sema::FunctionScopeInfo * getEnclosingFunction() const
Definition: Sema.cpp:2346
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
ExprResult ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, IdentifierInfo &propertyName, SourceLocation receiverNameLoc, SourceLocation propertyNameLoc)
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:3213
ObjCMethodDecl * DictionaryWithObjectsMethod
The declaration of the dictionaryWithObjects:forKeys:count: method.
Definition: Sema.h:12460
ExprResult checkUnknownAnyArg(SourceLocation callLoc, Expr *result, QualType &paramType)
Type-check an expression that's being passed to an __unknown_anytype parameter.
Definition: SemaExpr.cpp:21663
ObjCInterfaceDecl * NSValueDecl
The declaration of the Objective-C NSValue class.
Definition: Sema.h:12427
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:4377
CompoundStmt * getSubStmt()
Definition: Expr.h:4394
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:1171
StringRef getString() const
Definition: Expr.h:1850
The top declaration context.
Definition: Decl.h:84
Represents a declaration of a type.
Definition: Decl.h:3357
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Decl.h:3384
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:4865
A container of type source information.
Definition: Type.h:6873
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:6884
The base class of the type hierarchy.
Definition: Type.h:1606
bool isBlockPointerType() const
Definition: Type.h:7162
const ObjCObjectPointerType * getAsObjCQualifiedClassType() const
Definition: Type.cpp:1778
bool isVoidType() const
Definition: Type.h:7443
const ObjCObjectPointerType * getAsObjCQualifiedIdType() const
Definition: Type.cpp:1768
bool isObjCARCBridgableType() const
Determine whether the given type T is a "bridgable" Objective-C type, which is either an Objective-C ...
Definition: Type.cpp:4787
bool isPointerType() const
Definition: Type.h:7154
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: Type.h:7479
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7724
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
Definition: Type.cpp:1796
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
Definition: Type.cpp:1995
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:651
bool canHaveNullability(bool ResultIfUnknown=true) const
Determine whether the given type can have a nullability specifier applied to it, i....
Definition: Type.cpp:4529
bool isBuiltinType() const
Helper methods to distinguish type categories.
Definition: Type.h:7240
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2420
bool isCARCBridgableType() const
Determine whether the given type T is a "bridgeable" C type.
Definition: Type.cpp:4792
bool isObjCBoxableRecordType() const
Definition: Type.cpp:595
bool isObjCIdType() const
Definition: Type.h:7315
bool isObjCClassOrClassKindOfType() const
Whether the type is Objective-C 'Class' or a __kindof type of an Class type, e.g.,...
Definition: Type.cpp:732
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition: Type.h:7710
bool isObjCObjectPointerType() const
Definition: Type.h:7282
bool isObjCQualifiedClassType() const
Definition: Type.h:7309
bool isObjCClassType() const
Definition: Type.h:7321
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:1574
const ObjCObjectType * getAsObjCInterfaceType() const
Definition: Type.cpp:1788
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:706
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7657
bool isObjCRetainableType() const
Definition: Type.cpp:4758
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
Definition: Type.cpp:4516
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3399
QualType getUnderlyingType() const
Definition: Decl.h:3454
TypedefNameDecl * getDecl() const
Definition: Type.h:4760
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:2182
Expr * getSubExpr() const
Definition: Expr.h:2227
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:4824
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:54
NullabilityKind
Describes the nullability of a particular type.
Definition: Specifiers.h:332
@ 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
U cast(CodeGen::Address addr)
Definition: Address.h:152
@ Class
The "class" keyword introduces the elaborated-type-specifier.
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