brintos

brintos / llvm-project-archived public Read only

0
0
Text · 204.3 KiB · 4daf017 Raw
5247 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9//  This file implements semantic analysis for Objective-C expressions.10//11//===----------------------------------------------------------------------===//12 13#include "clang/AST/ASTContext.h"14#include "clang/AST/Availability.h"15#include "clang/AST/DeclObjC.h"16#include "clang/AST/ExprObjC.h"17#include "clang/AST/StmtVisitor.h"18#include "clang/AST/TypeLoc.h"19#include "clang/Analysis/DomainSpecific/CocoaConventions.h"20#include "clang/Basic/Builtins.h"21#include "clang/Basic/TargetInfo.h"22#include "clang/Edit/Commit.h"23#include "clang/Edit/Rewriters.h"24#include "clang/Lex/Preprocessor.h"25#include "clang/Sema/Initialization.h"26#include "clang/Sema/Lookup.h"27#include "clang/Sema/Scope.h"28#include "clang/Sema/ScopeInfo.h"29#include "clang/Sema/SemaObjC.h"30#include "llvm/Support/ConvertUTF.h"31#include <optional>32 33using namespace clang;34using namespace sema;35using llvm::ArrayRef;36 37ExprResult SemaObjC::ParseObjCStringLiteral(SourceLocation *AtLocs,38                                            ArrayRef<Expr *> Strings) {39  ASTContext &Context = getASTContext();40  // Most ObjC strings are formed out of a single piece.  However, we *can*41  // have strings formed out of multiple @ strings with multiple pptokens in42  // each one, e.g. @"foo" "bar" @"baz" "qux"   which need to be turned into one43  // StringLiteral for ObjCStringLiteral to hold onto.44  StringLiteral *S = cast<StringLiteral>(Strings[0]);45 46  // If we have a multi-part string, merge it all together.47  if (Strings.size() != 1) {48    // Concatenate objc strings.49    SmallString<128> StrBuf;50    SmallVector<SourceLocation, 8> StrLocs;51 52    for (Expr *E : Strings) {53      S = cast<StringLiteral>(E);54 55      // ObjC strings can't be wide or UTF.56      if (!S->isOrdinary()) {57        Diag(S->getBeginLoc(), diag::err_cfstring_literal_not_string_constant)58            << S->getSourceRange();59        return true;60      }61 62      // Append the string.63      StrBuf += S->getString();64 65      // Get the locations of the string tokens.66      StrLocs.append(S->tokloc_begin(), S->tokloc_end());67    }68 69    // Create the aggregate string with the appropriate content and location70    // information.71    const ConstantArrayType *CAT = Context.getAsConstantArrayType(S->getType());72    assert(CAT && "String literal not of constant array type!");73    QualType StrTy = Context.getConstantArrayType(74        CAT->getElementType(), llvm::APInt(32, StrBuf.size() + 1), nullptr,75        CAT->getSizeModifier(), CAT->getIndexTypeCVRQualifiers());76    S = StringLiteral::Create(Context, StrBuf, StringLiteralKind::Ordinary,77                              /*Pascal=*/false, StrTy, StrLocs);78  }79 80  return BuildObjCStringLiteral(AtLocs[0], S);81}82 83ExprResult SemaObjC::BuildObjCStringLiteral(SourceLocation AtLoc,84                                            StringLiteral *S) {85  ASTContext &Context = getASTContext();86  // Verify that this composite string is acceptable for ObjC strings.87  if (CheckObjCString(S))88    return true;89 90  // Initialize the constant string interface lazily. This assumes91  // the NSString interface is seen in this translation unit. Note: We92  // don't use NSConstantString, since the runtime team considers this93  // interface private (even though it appears in the header files).94  QualType Ty = Context.getObjCConstantStringInterface();95  if (!Ty.isNull()) {96    Ty = Context.getObjCObjectPointerType(Ty);97  } else if (getLangOpts().NoConstantCFStrings) {98    IdentifierInfo *NSIdent=nullptr;99    std::string StringClass(getLangOpts().ObjCConstantStringClass);100 101    if (StringClass.empty())102      NSIdent = &Context.Idents.get("NSConstantString");103    else104      NSIdent = &Context.Idents.get(StringClass);105 106    NamedDecl *IF = SemaRef.LookupSingleName(SemaRef.TUScope, NSIdent, AtLoc,107                                             Sema::LookupOrdinaryName);108    if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {109      Context.setObjCConstantStringInterface(StrIF);110      Ty = Context.getObjCConstantStringInterface();111      Ty = Context.getObjCObjectPointerType(Ty);112    } else {113      // If there is no NSConstantString interface defined then treat this114      // as error and recover from it.115      Diag(S->getBeginLoc(), diag::err_no_nsconstant_string_class)116          << NSIdent << S->getSourceRange();117      Ty = Context.getObjCIdType();118    }119  } else {120    IdentifierInfo *NSIdent = NSAPIObj->getNSClassId(NSAPI::ClassId_NSString);121    NamedDecl *IF = SemaRef.LookupSingleName(SemaRef.TUScope, NSIdent, AtLoc,122                                             Sema::LookupOrdinaryName);123    if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {124      Context.setObjCConstantStringInterface(StrIF);125      Ty = Context.getObjCConstantStringInterface();126      Ty = Context.getObjCObjectPointerType(Ty);127    } else {128      // If there is no NSString interface defined, implicitly declare129      // a @class NSString; and use that instead. This is to make sure130      // type of an NSString literal is represented correctly, instead of131      // being an 'id' type.132      Ty = Context.getObjCNSStringType();133      if (Ty.isNull()) {134        ObjCInterfaceDecl *NSStringIDecl =135          ObjCInterfaceDecl::Create (Context,136                                     Context.getTranslationUnitDecl(),137                                     SourceLocation(), NSIdent,138                                     nullptr, nullptr, SourceLocation());139        Ty = Context.getObjCInterfaceType(NSStringIDecl);140        Context.setObjCNSStringType(Ty);141      }142      Ty = Context.getObjCObjectPointerType(Ty);143    }144  }145 146  return new (Context) ObjCStringLiteral(S, Ty, AtLoc);147}148 149/// Emits an error if the given method does not exist, or if the return150/// type is not an Objective-C object.151static bool validateBoxingMethod(Sema &S, SourceLocation Loc,152                                 const ObjCInterfaceDecl *Class,153                                 Selector Sel, const ObjCMethodDecl *Method) {154  if (!Method) {155    // FIXME: Is there a better way to avoid quotes than using getName()?156    S.Diag(Loc, diag::err_undeclared_boxing_method) << Sel << Class->getName();157    return false;158  }159 160  // Make sure the return type is reasonable.161  QualType ReturnType = Method->getReturnType();162  if (!ReturnType->isObjCObjectPointerType()) {163    S.Diag(Loc, diag::err_objc_literal_method_sig)164      << Sel;165    S.Diag(Method->getLocation(), diag::note_objc_literal_method_return)166      << ReturnType;167    return false;168  }169 170  return true;171}172 173/// Maps ObjCLiteralKind to NSClassIdKindKind174static NSAPI::NSClassIdKindKind175ClassKindFromLiteralKind(SemaObjC::ObjCLiteralKind LiteralKind) {176  switch (LiteralKind) {177  case SemaObjC::LK_Array:178    return NSAPI::ClassId_NSArray;179  case SemaObjC::LK_Dictionary:180    return NSAPI::ClassId_NSDictionary;181  case SemaObjC::LK_Numeric:182    return NSAPI::ClassId_NSNumber;183  case SemaObjC::LK_String:184    return NSAPI::ClassId_NSString;185  case SemaObjC::LK_Boxed:186    return NSAPI::ClassId_NSValue;187 188  // there is no corresponding matching189  // between LK_None/LK_Block and NSClassIdKindKind190  case SemaObjC::LK_Block:191  case SemaObjC::LK_None:192    break;193  }194  llvm_unreachable("LiteralKind can't be converted into a ClassKind");195}196 197/// Validates ObjCInterfaceDecl availability.198/// ObjCInterfaceDecl, used to create ObjC literals, should be defined199/// if clang not in a debugger mode.200static bool201ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl,202                                 SourceLocation Loc,203                                 SemaObjC::ObjCLiteralKind LiteralKind) {204  if (!Decl) {205    NSAPI::NSClassIdKindKind Kind = ClassKindFromLiteralKind(LiteralKind);206    IdentifierInfo *II = S.ObjC().NSAPIObj->getNSClassId(Kind);207    S.Diag(Loc, diag::err_undeclared_objc_literal_class)208      << II->getName() << LiteralKind;209    return false;210  } else if (!Decl->hasDefinition() && !S.getLangOpts().DebuggerObjCLiteral) {211    S.Diag(Loc, diag::err_undeclared_objc_literal_class)212      << Decl->getName() << LiteralKind;213    S.Diag(Decl->getLocation(), diag::note_forward_class);214    return false;215  }216 217  return true;218}219 220/// Looks up ObjCInterfaceDecl of a given NSClassIdKindKind.221/// Used to create ObjC literals, such as NSDictionary (@{}),222/// NSArray (@[]) and Boxed Expressions (@())223static ObjCInterfaceDecl *224LookupObjCInterfaceDeclForLiteral(Sema &S, SourceLocation Loc,225                                  SemaObjC::ObjCLiteralKind LiteralKind) {226  NSAPI::NSClassIdKindKind ClassKind = ClassKindFromLiteralKind(LiteralKind);227  IdentifierInfo *II = S.ObjC().NSAPIObj->getNSClassId(ClassKind);228  NamedDecl *IF = S.LookupSingleName(S.TUScope, II, Loc,229                                     Sema::LookupOrdinaryName);230  ObjCInterfaceDecl *ID = dyn_cast_or_null<ObjCInterfaceDecl>(IF);231  if (!ID && S.getLangOpts().DebuggerObjCLiteral) {232    ASTContext &Context = S.Context;233    TranslationUnitDecl *TU = Context.getTranslationUnitDecl();234    ID = ObjCInterfaceDecl::Create (Context, TU, SourceLocation(), II,235                                    nullptr, nullptr, SourceLocation());236  }237 238  if (!ValidateObjCLiteralInterfaceDecl(S, ID, Loc, LiteralKind)) {239    ID = nullptr;240  }241 242  return ID;243}244 245/// Retrieve the NSNumber factory method that should be used to create246/// an Objective-C literal for the given type.247static ObjCMethodDecl *getNSNumberFactoryMethod(SemaObjC &S, SourceLocation Loc,248                                                QualType NumberType,249                                                bool isLiteral = false,250                                                SourceRange R = SourceRange()) {251  std::optional<NSAPI::NSNumberLiteralMethodKind> Kind =252      S.NSAPIObj->getNSNumberFactoryMethodKind(NumberType);253 254  if (!Kind) {255    if (isLiteral) {256      S.Diag(Loc, diag::err_invalid_nsnumber_type)257        << NumberType << R;258    }259    return nullptr;260  }261 262  // If we already looked up this method, we're done.263  if (S.NSNumberLiteralMethods[*Kind])264    return S.NSNumberLiteralMethods[*Kind];265 266  Selector Sel = S.NSAPIObj->getNSNumberLiteralSelector(*Kind,267                                                        /*Instance=*/false);268 269  ASTContext &CX = S.SemaRef.Context;270 271  // Look up the NSNumber class, if we haven't done so already. It's cached272  // in the Sema instance.273  if (!S.NSNumberDecl) {274    S.NSNumberDecl =275        LookupObjCInterfaceDeclForLiteral(S.SemaRef, Loc, SemaObjC::LK_Numeric);276    if (!S.NSNumberDecl) {277      return nullptr;278    }279  }280 281  if (S.NSNumberPointer.isNull()) {282    // generate the pointer to NSNumber type.283    QualType NSNumberObject = CX.getObjCInterfaceType(S.NSNumberDecl);284    S.NSNumberPointer = CX.getObjCObjectPointerType(NSNumberObject);285  }286 287  // Look for the appropriate method within NSNumber.288  ObjCMethodDecl *Method = S.NSNumberDecl->lookupClassMethod(Sel);289  if (!Method && S.getLangOpts().DebuggerObjCLiteral) {290    // create a stub definition this NSNumber factory method.291    TypeSourceInfo *ReturnTInfo = nullptr;292    Method = ObjCMethodDecl::Create(293        CX, SourceLocation(), SourceLocation(), Sel, S.NSNumberPointer,294        ReturnTInfo, S.NSNumberDecl,295        /*isInstance=*/false, /*isVariadic=*/false,296        /*isPropertyAccessor=*/false,297        /*isSynthesizedAccessorStub=*/false,298        /*isImplicitlyDeclared=*/true,299        /*isDefined=*/false, ObjCImplementationControl::Required,300        /*HasRelatedResultType=*/false);301    ParmVarDecl *value =302        ParmVarDecl::Create(S.SemaRef.Context, Method, SourceLocation(),303                            SourceLocation(), &CX.Idents.get("value"),304                            NumberType, /*TInfo=*/nullptr, SC_None, nullptr);305    Method->setMethodParams(S.SemaRef.Context, value, {});306  }307 308  if (!validateBoxingMethod(S.SemaRef, Loc, S.NSNumberDecl, Sel, Method))309    return nullptr;310 311  // Note: if the parameter type is out-of-line, we'll catch it later in the312  // implicit conversion.313 314  S.NSNumberLiteralMethods[*Kind] = Method;315  return Method;316}317 318/// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the319/// numeric literal expression. Type of the expression will be "NSNumber *".320ExprResult SemaObjC::BuildObjCNumericLiteral(SourceLocation AtLoc,321                                             Expr *Number) {322  ASTContext &Context = getASTContext();323  // Determine the type of the literal.324  QualType NumberType = Number->getType();325  if (CharacterLiteral *Char = dyn_cast<CharacterLiteral>(Number)) {326    // In C, character literals have type 'int'. That's not the type we want327    // to use to determine the Objective-c literal kind.328    switch (Char->getKind()) {329    case CharacterLiteralKind::Ascii:330    case CharacterLiteralKind::UTF8:331      NumberType = Context.CharTy;332      break;333 334    case CharacterLiteralKind::Wide:335      NumberType = Context.getWideCharType();336      break;337 338    case CharacterLiteralKind::UTF16:339      NumberType = Context.Char16Ty;340      break;341 342    case CharacterLiteralKind::UTF32:343      NumberType = Context.Char32Ty;344      break;345    }346  }347 348  // Look for the appropriate method within NSNumber.349  // Construct the literal.350  SourceRange NR(Number->getSourceRange());351  ObjCMethodDecl *Method = getNSNumberFactoryMethod(*this, AtLoc, NumberType,352                                                    true, NR);353  if (!Method)354    return ExprError();355 356  // Convert the number to the type that the parameter expects.357  ParmVarDecl *ParamDecl = Method->parameters()[0];358  InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,359                                                                    ParamDecl);360  ExprResult ConvertedNumber =361      SemaRef.PerformCopyInitialization(Entity, SourceLocation(), Number);362  if (ConvertedNumber.isInvalid())363    return ExprError();364  Number = ConvertedNumber.get();365 366  // Use the effective source range of the literal, including the leading '@'.367  return SemaRef.MaybeBindToTemporary(new (Context) ObjCBoxedExpr(368      Number, NSNumberPointer, Method, SourceRange(AtLoc, NR.getEnd())));369}370 371ExprResult SemaObjC::ActOnObjCBoolLiteral(SourceLocation AtLoc,372                                          SourceLocation ValueLoc, bool Value) {373  ASTContext &Context = getASTContext();374  ExprResult Inner;375  if (getLangOpts().CPlusPlus) {376    Inner = SemaRef.ActOnCXXBoolLiteral(ValueLoc,377                                        Value ? tok::kw_true : tok::kw_false);378  } else {379    // C doesn't actually have a way to represent literal values of type380    // _Bool. So, we'll use 0/1 and implicit cast to _Bool.381    Inner = SemaRef.ActOnIntegerConstant(ValueLoc, Value ? 1 : 0);382    Inner = SemaRef.ImpCastExprToType(Inner.get(), Context.BoolTy,383                                      CK_IntegralToBoolean);384  }385 386  return BuildObjCNumericLiteral(AtLoc, Inner.get());387}388 389/// Check that the given expression is a valid element of an Objective-C390/// collection literal.391static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element,392                                                    QualType T,393                                                    bool ArrayLiteral = false) {394  // If the expression is type-dependent, there's nothing for us to do.395  if (Element->isTypeDependent())396    return Element;397 398  ExprResult Result = S.CheckPlaceholderExpr(Element);399  if (Result.isInvalid())400    return ExprError();401  Element = Result.get();402 403  // In C++, check for an implicit conversion to an Objective-C object pointer404  // type.405  if (S.getLangOpts().CPlusPlus && Element->getType()->isRecordType()) {406    InitializedEntity Entity407      = InitializedEntity::InitializeParameter(S.Context, T,408                                               /*Consumed=*/false);409    InitializationKind Kind = InitializationKind::CreateCopy(410        Element->getBeginLoc(), SourceLocation());411    InitializationSequence Seq(S, Entity, Kind, Element);412    if (!Seq.Failed())413      return Seq.Perform(S, Entity, Kind, Element);414  }415 416  Expr *OrigElement = Element;417 418  // Perform lvalue-to-rvalue conversion.419  Result = S.DefaultLvalueConversion(Element);420  if (Result.isInvalid())421    return ExprError();422  Element = Result.get();423 424  // Make sure that we have an Objective-C pointer type or block.425  if (!Element->getType()->isObjCObjectPointerType() &&426      !Element->getType()->isBlockPointerType()) {427    bool Recovered = false;428 429    // If this is potentially an Objective-C numeric literal, add the '@'.430    if (isa<IntegerLiteral>(OrigElement) ||431        isa<CharacterLiteral>(OrigElement) ||432        isa<FloatingLiteral>(OrigElement) ||433        isa<ObjCBoolLiteralExpr>(OrigElement) ||434        isa<CXXBoolLiteralExpr>(OrigElement)) {435      if (S.ObjC().NSAPIObj->getNSNumberFactoryMethodKind(436              OrigElement->getType())) {437        int Which = isa<CharacterLiteral>(OrigElement) ? 1438                  : (isa<CXXBoolLiteralExpr>(OrigElement) ||439                     isa<ObjCBoolLiteralExpr>(OrigElement)) ? 2440                  : 3;441 442        S.Diag(OrigElement->getBeginLoc(), diag::err_box_literal_collection)443            << Which << OrigElement->getSourceRange()444            << FixItHint::CreateInsertion(OrigElement->getBeginLoc(), "@");445 446        Result = S.ObjC().BuildObjCNumericLiteral(OrigElement->getBeginLoc(),447                                                  OrigElement);448        if (Result.isInvalid())449          return ExprError();450 451        Element = Result.get();452        Recovered = true;453      }454    }455    // If this is potentially an Objective-C string literal, add the '@'.456    else if (StringLiteral *String = dyn_cast<StringLiteral>(OrigElement)) {457      if (String->isOrdinary()) {458        S.Diag(OrigElement->getBeginLoc(), diag::err_box_literal_collection)459            << 0 << OrigElement->getSourceRange()460            << FixItHint::CreateInsertion(OrigElement->getBeginLoc(), "@");461 462        Result =463            S.ObjC().BuildObjCStringLiteral(OrigElement->getBeginLoc(), String);464        if (Result.isInvalid())465          return ExprError();466 467        Element = Result.get();468        Recovered = true;469      }470    }471 472    if (!Recovered) {473      S.Diag(Element->getBeginLoc(), diag::err_invalid_collection_element)474          << Element->getType();475      return ExprError();476    }477  }478  if (ArrayLiteral)479    if (ObjCStringLiteral *getString =480          dyn_cast<ObjCStringLiteral>(OrigElement)) {481      if (StringLiteral *SL = getString->getString()) {482        unsigned numConcat = SL->getNumConcatenated();483        if (numConcat > 1) {484          // Only warn if the concatenated string doesn't come from a macro.485          bool hasMacro = false;486          for (unsigned i = 0; i < numConcat ; ++i)487            if (SL->getStrTokenLoc(i).isMacroID()) {488              hasMacro = true;489              break;490            }491          if (!hasMacro)492            S.Diag(Element->getBeginLoc(),493                   diag::warn_concatenated_nsarray_literal)494                << Element->getType();495        }496      }497    }498 499  // Make sure that the element has the type that the container factory500  // function expects.501  return S.PerformCopyInitialization(502      InitializedEntity::InitializeParameter(S.Context, T,503                                             /*Consumed=*/false),504      Element->getBeginLoc(), Element);505}506 507ExprResult SemaObjC::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {508  ASTContext &Context = getASTContext();509  if (ValueExpr->isTypeDependent()) {510    ObjCBoxedExpr *BoxedExpr =511      new (Context) ObjCBoxedExpr(ValueExpr, Context.DependentTy, nullptr, SR);512    return BoxedExpr;513  }514  ObjCMethodDecl *BoxingMethod = nullptr;515  QualType BoxedType;516  // Convert the expression to an RValue, so we can check for pointer types...517  ExprResult RValue = SemaRef.DefaultFunctionArrayLvalueConversion(ValueExpr);518  if (RValue.isInvalid()) {519    return ExprError();520  }521  SourceLocation Loc = SR.getBegin();522  ValueExpr = RValue.get();523  QualType ValueType(ValueExpr->getType());524  if (const PointerType *PT = ValueType->getAs<PointerType>()) {525    QualType PointeeType = PT->getPointeeType();526    if (Context.hasSameUnqualifiedType(PointeeType, Context.CharTy)) {527 528      if (!NSStringDecl) {529        NSStringDecl =530            LookupObjCInterfaceDeclForLiteral(SemaRef, Loc, LK_String);531        if (!NSStringDecl) {532          return ExprError();533        }534        QualType NSStringObject = Context.getObjCInterfaceType(NSStringDecl);535        NSStringPointer = Context.getObjCObjectPointerType(NSStringObject);536      }537 538      // The boxed expression can be emitted as a compile time constant if it is539      // a string literal whose character encoding is compatible with UTF-8.540      if (auto *CE = dyn_cast<ImplicitCastExpr>(ValueExpr))541        if (CE->getCastKind() == CK_ArrayToPointerDecay)542          if (auto *SL =543                  dyn_cast<StringLiteral>(CE->getSubExpr()->IgnoreParens())) {544            assert((SL->isOrdinary() || SL->isUTF8()) &&545                   "unexpected character encoding");546            StringRef Str = SL->getString();547            const llvm::UTF8 *StrBegin = Str.bytes_begin();548            const llvm::UTF8 *StrEnd = Str.bytes_end();549            // Check that this is a valid UTF-8 string.550            if (llvm::isLegalUTF8String(&StrBegin, StrEnd)) {551              BoxedType = Context.getAttributedType(NullabilityKind::NonNull,552                  NSStringPointer, NSStringPointer);553              return new (Context) ObjCBoxedExpr(CE, BoxedType, nullptr, SR);554            }555 556            Diag(SL->getBeginLoc(), diag::warn_objc_boxing_invalid_utf8_string)557                << NSStringPointer << SL->getSourceRange();558          }559 560      if (!StringWithUTF8StringMethod) {561        IdentifierInfo *II = &Context.Idents.get("stringWithUTF8String");562        Selector stringWithUTF8String = Context.Selectors.getUnarySelector(II);563 564        // Look for the appropriate method within NSString.565        BoxingMethod = NSStringDecl->lookupClassMethod(stringWithUTF8String);566        if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) {567          // Debugger needs to work even if NSString hasn't been defined.568          TypeSourceInfo *ReturnTInfo = nullptr;569          ObjCMethodDecl *M = ObjCMethodDecl::Create(570              Context, SourceLocation(), SourceLocation(), stringWithUTF8String,571              NSStringPointer, ReturnTInfo, NSStringDecl,572              /*isInstance=*/false, /*isVariadic=*/false,573              /*isPropertyAccessor=*/false,574              /*isSynthesizedAccessorStub=*/false,575              /*isImplicitlyDeclared=*/true,576              /*isDefined=*/false, ObjCImplementationControl::Required,577              /*HasRelatedResultType=*/false);578          QualType ConstCharType = Context.CharTy.withConst();579          ParmVarDecl *value =580            ParmVarDecl::Create(Context, M,581                                SourceLocation(), SourceLocation(),582                                &Context.Idents.get("value"),583                                Context.getPointerType(ConstCharType),584                                /*TInfo=*/nullptr,585                                SC_None, nullptr);586          M->setMethodParams(Context, value, {});587          BoxingMethod = M;588        }589 590        if (!validateBoxingMethod(SemaRef, Loc, NSStringDecl,591                                  stringWithUTF8String, BoxingMethod))592          return ExprError();593 594        StringWithUTF8StringMethod = BoxingMethod;595      }596 597      BoxingMethod = StringWithUTF8StringMethod;598      BoxedType = NSStringPointer;599      // Transfer the nullability from method's return type.600      std::optional<NullabilityKind> Nullability =601          BoxingMethod->getReturnType()->getNullability();602      if (Nullability)603        BoxedType =604            Context.getAttributedType(*Nullability, BoxedType, BoxedType);605    }606  } else if (ValueType->isBuiltinType()) {607    // The other types we support are numeric, char and BOOL/bool. We could also608    // provide limited support for structure types, such as NSRange, NSRect, and609    // NSSize. See NSValue (NSValueGeometryExtensions) in <Foundation/NSGeometry.h>610    // for more details.611 612    // Check for a top-level character literal.613    if (const CharacterLiteral *Char =614        dyn_cast<CharacterLiteral>(ValueExpr->IgnoreParens())) {615      // In C, character literals have type 'int'. That's not the type we want616      // to use to determine the Objective-c literal kind.617      switch (Char->getKind()) {618      case CharacterLiteralKind::Ascii:619      case CharacterLiteralKind::UTF8:620        ValueType = Context.CharTy;621        break;622 623      case CharacterLiteralKind::Wide:624        ValueType = Context.getWideCharType();625        break;626 627      case CharacterLiteralKind::UTF16:628        ValueType = Context.Char16Ty;629        break;630 631      case CharacterLiteralKind::UTF32:632        ValueType = Context.Char32Ty;633        break;634      }635    }636    // FIXME:  Do I need to do anything special with BoolTy expressions?637 638    // Look for the appropriate method within NSNumber.639    BoxingMethod = getNSNumberFactoryMethod(*this, Loc, ValueType);640    BoxedType = NSNumberPointer;641  } else if (const auto *ED = ValueType->getAsEnumDecl()) {642    if (!ED->isComplete()) {643      Diag(Loc, diag::err_objc_incomplete_boxed_expression_type)644        << ValueType << ValueExpr->getSourceRange();645      return ExprError();646    }647 648    BoxingMethod = getNSNumberFactoryMethod(*this, Loc, ED->getIntegerType());649    BoxedType = NSNumberPointer;650  } else if (ValueType->isObjCBoxableRecordType()) {651    // Support for structure types, that marked as objc_boxable652    // struct __attribute__((objc_boxable)) s { ... };653 654    // Look up the NSValue class, if we haven't done so already. It's cached655    // in the Sema instance.656    if (!NSValueDecl) {657      NSValueDecl = LookupObjCInterfaceDeclForLiteral(SemaRef, Loc, LK_Boxed);658      if (!NSValueDecl) {659        return ExprError();660      }661 662      // generate the pointer to NSValue type.663      QualType NSValueObject = Context.getObjCInterfaceType(NSValueDecl);664      NSValuePointer = Context.getObjCObjectPointerType(NSValueObject);665    }666 667    if (!ValueWithBytesObjCTypeMethod) {668      const IdentifierInfo *II[] = {&Context.Idents.get("valueWithBytes"),669                                    &Context.Idents.get("objCType")};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;677        ObjCMethodDecl *M = ObjCMethodDecl::Create(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 688        SmallVector<ParmVarDecl *, 2> Params;689 690        ParmVarDecl *bytes =691        ParmVarDecl::Create(Context, M,692                            SourceLocation(), SourceLocation(),693                            &Context.Idents.get("bytes"),694                            Context.VoidPtrTy.withConst(),695                            /*TInfo=*/nullptr,696                            SC_None, nullptr);697        Params.push_back(bytes);698 699        QualType ConstCharType = Context.CharTy.withConst();700        ParmVarDecl *type =701        ParmVarDecl::Create(Context, M,702                            SourceLocation(), SourceLocation(),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, {});710        BoxingMethod = M;711      }712 713      if (!validateBoxingMethod(SemaRef, 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  SemaRef.DiagnoseUseOfDecl(BoxingMethod, Loc);737 738  ExprResult ConvertedValueExpr;739  if (ValueType->isObjCBoxableRecordType()) {740    InitializedEntity IE = InitializedEntity::InitializeTemporary(ValueType);741    ConvertedValueExpr = SemaRef.PerformCopyInitialization(742        IE, ValueExpr->getExprLoc(), ValueExpr);743  } else {744    // Convert the expression to the type that the parameter requires.745    ParmVarDecl *ParamDecl = BoxingMethod->parameters()[0];746    InitializedEntity IE = InitializedEntity::InitializeParameter(Context,747                                                                  ParamDecl);748    ConvertedValueExpr =749        SemaRef.PerformCopyInitialization(IE, SourceLocation(), 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 SemaRef.MaybeBindToTemporary(BoxedExpr);760}761 762/// Build an ObjC subscript pseudo-object expression, given that763/// that's supported by the runtime.764ExprResult SemaObjC::BuildObjCSubscriptExpression(765    SourceLocation RB, Expr *BaseExpr, Expr *IndexExpr,766    ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod) {767  assert(!getLangOpts().isSubscriptPointerArithmetic());768  ASTContext &Context = getASTContext();769 770  // We can't get dependent types here; our callers should have771  // 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 could776  // be preserved here, although that might not actually work correctly.777  ExprResult Result = SemaRef.CheckPlaceholderExpr(IndexExpr);778  if (Result.isInvalid())779    return ExprError();780  IndexExpr = Result.get();781 782  // Perform lvalue-to-rvalue conversion on the base.783  Result = SemaRef.DefaultLvalueConversion(BaseExpr);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 794ExprResult SemaObjC::BuildObjCArrayLiteral(SourceRange SR,795                                           MultiExprArg Elements) {796  ASTContext &Context = getASTContext();797  SourceLocation Loc = SR.getBegin();798 799  if (!NSArrayDecl) {800    NSArrayDecl =801        LookupObjCInterfaceDeclForLiteral(SemaRef, Loc, SemaObjC::LK_Array);802    if (!NSArrayDecl) {803      return ExprError();804    }805  }806 807  // Find the arrayWithObjects:count: method, if we haven't done so already.808  QualType IdT = Context.getObjCIdType();809  if (!ArrayWithObjectsMethod) {810    Selector811      Sel = NSAPIObj->getNSArraySelector(NSAPI::NSArr_arrayWithObjectsCount);812    ObjCMethodDecl *Method = NSArrayDecl->lookupClassMethod(Sel);813    if (!Method && getLangOpts().DebuggerObjCLiteral) {814      TypeSourceInfo *ReturnTInfo = nullptr;815      Method = ObjCMethodDecl::Create(816          Context, SourceLocation(), SourceLocation(), Sel, IdT, ReturnTInfo,817          Context.getTranslationUnitDecl(), false /*Instance*/,818          false /*isVariadic*/,819          /*isPropertyAccessor=*/false, /*isSynthesizedAccessorStub=*/false,820          /*isImplicitlyDeclared=*/true, /*isDefined=*/false,821          ObjCImplementationControl::Required, false);822      SmallVector<ParmVarDecl *, 2> Params;823      ParmVarDecl *objects = ParmVarDecl::Create(Context, Method,824                                                 SourceLocation(),825                                                 SourceLocation(),826                                                 &Context.Idents.get("objects"),827                                                 Context.getPointerType(IdT),828                                                 /*TInfo=*/nullptr,829                                                 SC_None, nullptr);830      Params.push_back(objects);831      ParmVarDecl *cnt = ParmVarDecl::Create(Context, Method,832                                             SourceLocation(),833                                             SourceLocation(),834                                             &Context.Idents.get("cnt"),835                                             Context.UnsignedLongTy,836                                             /*TInfo=*/nullptr, SC_None,837                                             nullptr);838      Params.push_back(cnt);839      Method->setMethodParams(Context, Params, {});840    }841 842    if (!validateBoxingMethod(SemaRef, Loc, NSArrayDecl, Sel, Method))843      return ExprError();844 845    // Dig out the type that all elements should be converted to.846    QualType T = Method->parameters()[0]->getType();847    const PointerType *PtrT = T->getAs<PointerType>();848    if (!PtrT ||849        !Context.hasSameUnqualifiedType(PtrT->getPointeeType(), IdT)) {850      Diag(SR.getBegin(), diag::err_objc_literal_method_sig)851        << Sel;852      Diag(Method->parameters()[0]->getLocation(),853           diag::note_objc_literal_method_param)854        << 0 << T855        << Context.getPointerType(IdT.withConst());856      return ExprError();857    }858 859    // Check that the 'count' parameter is integral.860    if (!Method->parameters()[1]->getType()->isIntegerType()) {861      Diag(SR.getBegin(), diag::err_objc_literal_method_sig)862        << Sel;863      Diag(Method->parameters()[1]->getLocation(),864           diag::note_objc_literal_method_param)865        << 1866        << Method->parameters()[1]->getType()867        << "integral";868      return ExprError();869    }870 871    // We've found a good +arrayWithObjects:count: method. Save it!872    ArrayWithObjectsMethod = Method;873  }874 875  QualType ObjectsType = ArrayWithObjectsMethod->parameters()[0]->getType();876  QualType RequiredType = ObjectsType->castAs<PointerType>()->getPointeeType();877 878  // Check that each of the elements provided is valid in a collection literal,879  // performing conversions as necessary.880  Expr **ElementsBuffer = Elements.data();881  for (unsigned I = 0, N = Elements.size(); I != N; ++I) {882    ExprResult Converted = CheckObjCCollectionLiteralElement(883        SemaRef, ElementsBuffer[I], RequiredType, true);884    if (Converted.isInvalid())885      return ExprError();886 887    ElementsBuffer[I] = Converted.get();888  }889 890  QualType Ty891    = Context.getObjCObjectPointerType(892                                    Context.getObjCInterfaceType(NSArrayDecl));893 894  return SemaRef.MaybeBindToTemporary(ObjCArrayLiteral::Create(895      Context, Elements, Ty, ArrayWithObjectsMethod, SR));896}897 898/// Check for duplicate keys in an ObjC dictionary literal. For instance:899///   NSDictionary *nd = @{ @"foo" : @"bar", @"foo" : @"baz" };900static void901CheckObjCDictionaryLiteralDuplicateKeys(Sema &S,902                                        ObjCDictionaryLiteral *Literal) {903  if (Literal->isValueDependent() || Literal->isTypeDependent())904    return;905 906  // NSNumber has quite relaxed equality semantics (for instance, @YES is907  // considered equal to @1.0). For now, ignore floating points and just do a908  // 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 945      Expr::EvalResult Result;946      if (Boxed->EvaluateAsInt(Result, S.getASTContext(),947                               Expr::SE_AllowSideEffects)) {948        checkOneKey(IntegralKeys, Result.Val.getInt(), Loc);949      }950    }951  }952}953 954ExprResult SemaObjC::BuildObjCDictionaryLiteral(955    SourceRange SR, MutableArrayRef<ObjCDictionaryElement> Elements) {956  ASTContext &Context = getASTContext();957  SourceLocation Loc = SR.getBegin();958 959  if (!NSDictionaryDecl) {960    NSDictionaryDecl = LookupObjCInterfaceDeclForLiteral(961        SemaRef, Loc, SemaObjC::LK_Dictionary);962    if (!NSDictionaryDecl) {963      return ExprError();964    }965  }966 967  // Find the dictionaryWithObjects:forKeys:count: method, if we haven't done968  // so already.969  QualType IdT = Context.getObjCIdType();970  if (!DictionaryWithObjectsMethod) {971    Selector Sel = NSAPIObj->getNSDictionarySelector(972                               NSAPI::NSDict_dictionaryWithObjectsForKeysCount);973    ObjCMethodDecl *Method = NSDictionaryDecl->lookupClassMethod(Sel);974    if (!Method && getLangOpts().DebuggerObjCLiteral) {975      Method = ObjCMethodDecl::Create(976          Context, SourceLocation(), SourceLocation(), Sel, IdT,977          nullptr /*TypeSourceInfo */, Context.getTranslationUnitDecl(),978          false /*Instance*/, false /*isVariadic*/,979          /*isPropertyAccessor=*/false,980          /*isSynthesizedAccessorStub=*/false,981          /*isImplicitlyDeclared=*/true, /*isDefined=*/false,982          ObjCImplementationControl::Required, false);983      SmallVector<ParmVarDecl *, 3> Params;984      ParmVarDecl *objects = ParmVarDecl::Create(Context, Method,985                                                 SourceLocation(),986                                                 SourceLocation(),987                                                 &Context.Idents.get("objects"),988                                                 Context.getPointerType(IdT),989                                                 /*TInfo=*/nullptr, SC_None,990                                                 nullptr);991      Params.push_back(objects);992      ParmVarDecl *keys = ParmVarDecl::Create(Context, Method,993                                              SourceLocation(),994                                              SourceLocation(),995                                              &Context.Idents.get("keys"),996                                              Context.getPointerType(IdT),997                                              /*TInfo=*/nullptr, SC_None,998                                              nullptr);999      Params.push_back(keys);1000      ParmVarDecl *cnt = ParmVarDecl::Create(Context, Method,1001                                             SourceLocation(),1002                                             SourceLocation(),1003                                             &Context.Idents.get("cnt"),1004                                             Context.UnsignedLongTy,1005                                             /*TInfo=*/nullptr, SC_None,1006                                             nullptr);1007      Params.push_back(cnt);1008      Method->setMethodParams(Context, Params, {});1009    }1010 1011    if (!validateBoxingMethod(SemaRef, SR.getBegin(), NSDictionaryDecl, Sel,1012                              Method))1013      return ExprError();1014 1015    // Dig out the type that all values should be converted to.1016    QualType ValueT = Method->parameters()[0]->getType();1017    const PointerType *PtrValue = ValueT->getAs<PointerType>();1018    if (!PtrValue ||1019        !Context.hasSameUnqualifiedType(PtrValue->getPointeeType(), IdT)) {1020      Diag(SR.getBegin(), diag::err_objc_literal_method_sig)1021        << Sel;1022      Diag(Method->parameters()[0]->getLocation(),1023           diag::note_objc_literal_method_param)1024        << 0 << ValueT1025        << Context.getPointerType(IdT.withConst());1026      return ExprError();1027    }1028 1029    // Dig out the type that all keys should be converted to.1030    QualType KeyT = Method->parameters()[1]->getType();1031    const PointerType *PtrKey = KeyT->getAs<PointerType>();1032    if (!PtrKey ||1033        !Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),1034                                        IdT)) {1035      bool err = true;1036      if (PtrKey) {1037        if (QIDNSCopying.isNull()) {1038          // key argument of selector is id<NSCopying>?1039          if (ObjCProtocolDecl *NSCopyingPDecl =1040              LookupProtocol(&Context.Idents.get("NSCopying"), SR.getBegin())) {1041            ObjCProtocolDecl *PQ[] = {NSCopyingPDecl};1042            QIDNSCopying = Context.getObjCObjectType(1043                Context.ObjCBuiltinIdTy, {},1044                llvm::ArrayRef((ObjCProtocolDecl **)PQ, 1), false);1045            QIDNSCopying = Context.getObjCObjectPointerType(QIDNSCopying);1046          }1047        }1048        if (!QIDNSCopying.isNull())1049          err = !Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),1050                                                QIDNSCopying);1051      }1052 1053      if (err) {1054        Diag(SR.getBegin(), diag::err_objc_literal_method_sig)1055          << Sel;1056        Diag(Method->parameters()[1]->getLocation(),1057             diag::note_objc_literal_method_param)1058          << 1 << KeyT1059          << Context.getPointerType(IdT.withConst());1060        return ExprError();1061      }1062    }1063 1064    // Check that the 'count' parameter is integral.1065    QualType CountType = Method->parameters()[2]->getType();1066    if (!CountType->isIntegerType()) {1067      Diag(SR.getBegin(), diag::err_objc_literal_method_sig)1068        << Sel;1069      Diag(Method->parameters()[2]->getLocation(),1070           diag::note_objc_literal_method_param)1071        << 2 << CountType1072        << "integral";1073      return ExprError();1074    }1075 1076    // We've found a good +dictionaryWithObjects:keys:count: method; save it!1077    DictionaryWithObjectsMethod = Method;1078  }1079 1080  QualType ValuesT = DictionaryWithObjectsMethod->parameters()[0]->getType();1081  QualType ValueT = ValuesT->castAs<PointerType>()->getPointeeType();1082  QualType KeysT = DictionaryWithObjectsMethod->parameters()[1]->getType();1083  QualType KeyT = KeysT->castAs<PointerType>()->getPointeeType();1084 1085  // Check that each of the keys and values provided is valid in a collection1086  // literal, performing conversions as necessary.1087  bool HasPackExpansions = false;1088  for (ObjCDictionaryElement &Element : Elements) {1089    // Check the key.1090    ExprResult Key =1091        CheckObjCCollectionLiteralElement(SemaRef, Element.Key, KeyT);1092    if (Key.isInvalid())1093      return ExprError();1094 1095    // Check the value.1096    ExprResult Value =1097        CheckObjCCollectionLiteralElement(SemaRef, Element.Value, ValueT);1098    if (Value.isInvalid())1099      return ExprError();1100 1101    Element.Key = Key.get();1102    Element.Value = Value.get();1103 1104    if (Element.EllipsisLoc.isInvalid())1105      continue;1106 1107    if (!Element.Key->containsUnexpandedParameterPack() &&1108        !Element.Value->containsUnexpandedParameterPack()) {1109      Diag(Element.EllipsisLoc,1110           diag::err_pack_expansion_without_parameter_packs)1111          << SourceRange(Element.Key->getBeginLoc(),1112                         Element.Value->getEndLoc());1113      return ExprError();1114    }1115 1116    HasPackExpansions = true;1117  }1118 1119  QualType Ty = Context.getObjCObjectPointerType(1120      Context.getObjCInterfaceType(NSDictionaryDecl));1121 1122  auto *Literal =1123      ObjCDictionaryLiteral::Create(Context, Elements, HasPackExpansions, Ty,1124                                    DictionaryWithObjectsMethod, SR);1125  CheckObjCDictionaryLiteralDuplicateKeys(SemaRef, Literal);1126  return SemaRef.MaybeBindToTemporary(Literal);1127}1128 1129ExprResult SemaObjC::BuildObjCEncodeExpression(SourceLocation AtLoc,1130                                               TypeSourceInfo *EncodedTypeInfo,1131                                               SourceLocation RParenLoc) {1132  ASTContext &Context = getASTContext();1133  QualType EncodedType = EncodedTypeInfo->getType();1134  QualType StrTy;1135  if (EncodedType->isDependentType())1136    StrTy = Context.DependentTy;1137  else {1138    if (!EncodedType->getAsArrayTypeUnsafe() && //// Incomplete array is handled.1139        !EncodedType->isVoidType()) // void is handled too.1140      if (SemaRef.RequireCompleteType(AtLoc, EncodedType,1141                                      diag::err_incomplete_type_objc_at_encode,1142                                      EncodedTypeInfo->getTypeLoc()))1143        return ExprError();1144 1145    std::string Str;1146    QualType NotEncodedT;1147    Context.getObjCEncodingForType(EncodedType, Str, nullptr, &NotEncodedT);1148    if (!NotEncodedT.isNull())1149      Diag(AtLoc, diag::warn_incomplete_encoded_type)1150        << EncodedType << NotEncodedT;1151 1152    // The type of @encode is the same as the type of the corresponding string,1153    // which is an array type.1154    StrTy = Context.getStringLiteralArrayType(Context.CharTy, Str.size());1155  }1156 1157  return new (Context) ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc);1158}1159 1160ExprResult SemaObjC::ParseObjCEncodeExpression(SourceLocation AtLoc,1161                                               SourceLocation EncodeLoc,1162                                               SourceLocation LParenLoc,1163                                               ParsedType ty,1164                                               SourceLocation RParenLoc) {1165  ASTContext &Context = getASTContext();1166  // FIXME: Preserve type source info ?1167  TypeSourceInfo *TInfo;1168  QualType EncodedType = SemaRef.GetTypeFromParser(ty, &TInfo);1169  if (!TInfo)1170    TInfo = Context.getTrivialTypeSourceInfo(1171        EncodedType, SemaRef.getLocForEndOfToken(LParenLoc));1172 1173  return BuildObjCEncodeExpression(AtLoc, TInfo, RParenLoc);1174}1175 1176static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S,1177                                               SourceLocation AtLoc,1178                                               SourceLocation LParenLoc,1179                                               SourceLocation RParenLoc,1180                                               ObjCMethodDecl *Method,1181                                               ObjCMethodList &MethList) {1182  ObjCMethodList *M = &MethList;1183  bool Warned = false;1184  for (M = M->getNext(); M; M=M->getNext()) {1185    ObjCMethodDecl *MatchingMethodDecl = M->getMethod();1186    if (MatchingMethodDecl == Method ||1187        isa<ObjCImplDecl>(MatchingMethodDecl->getDeclContext()) ||1188        MatchingMethodDecl->getSelector() != Method->getSelector())1189      continue;1190    if (!S.ObjC().MatchTwoMethodDeclarations(Method, MatchingMethodDecl,1191                                             SemaObjC::MMS_loose)) {1192      if (!Warned) {1193        Warned = true;1194        S.Diag(AtLoc, diag::warn_multiple_selectors)1195          << Method->getSelector() << FixItHint::CreateInsertion(LParenLoc, "(")1196          << FixItHint::CreateInsertion(RParenLoc, ")");1197        S.Diag(Method->getLocation(), diag::note_method_declared_at)1198          << Method->getDeclName();1199      }1200      S.Diag(MatchingMethodDecl->getLocation(), diag::note_method_declared_at)1201        << MatchingMethodDecl->getDeclName();1202    }1203  }1204  return Warned;1205}1206 1207static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc,1208                                        ObjCMethodDecl *Method,1209                                        SourceLocation LParenLoc,1210                                        SourceLocation RParenLoc,1211                                        bool WarnMultipleSelectors) {1212  if (!WarnMultipleSelectors ||1213      S.Diags.isIgnored(diag::warn_multiple_selectors, SourceLocation()))1214    return;1215  bool Warned = false;1216  for (SemaObjC::GlobalMethodPool::iterator b = S.ObjC().MethodPool.begin(),1217                                            e = S.ObjC().MethodPool.end();1218       b != e; b++) {1219    // first, instance methods1220    ObjCMethodList &InstMethList = b->second.first;1221    if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,1222                                                      Method, InstMethList))1223      Warned = true;1224 1225    // second, class methods1226    ObjCMethodList &ClsMethList = b->second.second;1227    if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,1228                                                      Method, ClsMethList) || Warned)1229      return;1230  }1231}1232 1233static ObjCMethodDecl *LookupDirectMethodInMethodList(Sema &S, Selector Sel,1234                                                      ObjCMethodList &MethList,1235                                                      bool &onlyDirect,1236                                                      bool &anyDirect) {1237  (void)Sel;1238  ObjCMethodList *M = &MethList;1239  ObjCMethodDecl *DirectMethod = nullptr;1240  for (; M; M = M->getNext()) {1241    ObjCMethodDecl *Method = M->getMethod();1242    if (!Method)1243      continue;1244    assert(Method->getSelector() == Sel && "Method with wrong selector in method list");1245    if (Method->isDirectMethod()) {1246      anyDirect = true;1247      DirectMethod = Method;1248    } else1249      onlyDirect = false;1250  }1251 1252  return DirectMethod;1253}1254 1255// Search the global pool for (potentially) direct methods matching the given1256// selector. If a non-direct method is found, set \param onlyDirect to false. If1257// a direct method is found, set \param anyDirect to true. Returns a direct1258// method, if any.1259static ObjCMethodDecl *LookupDirectMethodInGlobalPool(Sema &S, Selector Sel,1260                                                      bool &onlyDirect,1261                                                      bool &anyDirect) {1262  auto Iter = S.ObjC().MethodPool.find(Sel);1263  if (Iter == S.ObjC().MethodPool.end())1264    return nullptr;1265 1266  ObjCMethodDecl *DirectInstance = LookupDirectMethodInMethodList(1267      S, Sel, Iter->second.first, onlyDirect, anyDirect);1268  ObjCMethodDecl *DirectClass = LookupDirectMethodInMethodList(1269      S, Sel, Iter->second.second, onlyDirect, anyDirect);1270 1271  return DirectInstance ? DirectInstance : DirectClass;1272}1273 1274static ObjCMethodDecl *findMethodInCurrentClass(Sema &S, Selector Sel) {1275  auto *CurMD = S.getCurMethodDecl();1276  if (!CurMD)1277    return nullptr;1278  ObjCInterfaceDecl *IFace = CurMD->getClassInterface();1279 1280  // The language enforce that only one direct method is present in a given1281  // class, so we just need to find one method in the current class to know1282  // whether Sel is potentially direct in this context.1283  if (ObjCMethodDecl *MD = IFace->lookupMethod(Sel, /*isInstance=*/true))1284    return MD;1285  if (ObjCMethodDecl *MD = IFace->lookupPrivateMethod(Sel, /*Instance=*/true))1286    return MD;1287  if (ObjCMethodDecl *MD = IFace->lookupMethod(Sel, /*isInstance=*/false))1288    return MD;1289  if (ObjCMethodDecl *MD = IFace->lookupPrivateMethod(Sel, /*Instance=*/false))1290    return MD;1291 1292  return nullptr;1293}1294 1295ExprResult SemaObjC::ParseObjCSelectorExpression(Selector Sel,1296                                                 SourceLocation AtLoc,1297                                                 SourceLocation SelLoc,1298                                                 SourceLocation LParenLoc,1299                                                 SourceLocation RParenLoc,1300                                                 bool WarnMultipleSelectors) {1301  ASTContext &Context = getASTContext();1302  ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,1303                             SourceRange(LParenLoc, RParenLoc));1304  if (!Method)1305    Method = LookupFactoryMethodInGlobalPool(Sel,1306                                          SourceRange(LParenLoc, RParenLoc));1307  if (!Method) {1308    if (const ObjCMethodDecl *OM = SelectorsForTypoCorrection(Sel)) {1309      Selector MatchedSel = OM->getSelector();1310      SourceRange SelectorRange(LParenLoc.getLocWithOffset(1),1311                                RParenLoc.getLocWithOffset(-1));1312      Diag(SelLoc, diag::warn_undeclared_selector_with_typo)1313        << Sel << MatchedSel1314        << FixItHint::CreateReplacement(SelectorRange, MatchedSel.getAsString());1315 1316    } else1317        Diag(SelLoc, diag::warn_undeclared_selector) << Sel;1318  } else {1319    DiagnoseMismatchedSelectors(SemaRef, AtLoc, Method, LParenLoc, RParenLoc,1320                                WarnMultipleSelectors);1321 1322    bool onlyDirect = true;1323    bool anyDirect = false;1324    ObjCMethodDecl *GlobalDirectMethod =1325        LookupDirectMethodInGlobalPool(SemaRef, Sel, onlyDirect, anyDirect);1326 1327    if (onlyDirect) {1328      Diag(AtLoc, diag::err_direct_selector_expression)1329          << Method->getSelector();1330      Diag(Method->getLocation(), diag::note_direct_method_declared_at)1331          << Method->getDeclName();1332    } else if (anyDirect) {1333      // If we saw any direct methods, see if we see a direct member of the1334      // current class. If so, the @selector will likely be used to refer to1335      // this direct method.1336      ObjCMethodDecl *LikelyTargetMethod =1337          findMethodInCurrentClass(SemaRef, Sel);1338      if (LikelyTargetMethod && LikelyTargetMethod->isDirectMethod()) {1339        Diag(AtLoc, diag::warn_potentially_direct_selector_expression) << Sel;1340        Diag(LikelyTargetMethod->getLocation(),1341             diag::note_direct_method_declared_at)1342            << LikelyTargetMethod->getDeclName();1343      } else if (!LikelyTargetMethod) {1344        // Otherwise, emit the "strict" variant of this diagnostic, unless1345        // LikelyTargetMethod is non-direct.1346        Diag(AtLoc, diag::warn_strict_potentially_direct_selector_expression)1347            << Sel;1348        Diag(GlobalDirectMethod->getLocation(),1349             diag::note_direct_method_declared_at)1350            << GlobalDirectMethod->getDeclName();1351      }1352    }1353  }1354 1355  if (Method &&1356      Method->getImplementationControl() !=1357          ObjCImplementationControl::Optional &&1358      !SemaRef.getSourceManager().isInSystemHeader(Method->getLocation()))1359    ReferencedSelectors.insert(std::make_pair(Sel, AtLoc));1360 1361  // In ARC, forbid the user from using @selector for1362  // retain/release/autorelease/dealloc/retainCount.1363  if (getLangOpts().ObjCAutoRefCount) {1364    switch (Sel.getMethodFamily()) {1365    case OMF_retain:1366    case OMF_release:1367    case OMF_autorelease:1368    case OMF_retainCount:1369    case OMF_dealloc:1370      Diag(AtLoc, diag::err_arc_illegal_selector) <<1371        Sel << SourceRange(LParenLoc, RParenLoc);1372      break;1373 1374    case OMF_None:1375    case OMF_alloc:1376    case OMF_copy:1377    case OMF_finalize:1378    case OMF_init:1379    case OMF_mutableCopy:1380    case OMF_new:1381    case OMF_self:1382    case OMF_initialize:1383    case OMF_performSelector:1384      break;1385    }1386  }1387  QualType Ty = Context.getObjCSelType();1388  return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);1389}1390 1391ExprResult SemaObjC::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,1392                                                 SourceLocation AtLoc,1393                                                 SourceLocation ProtoLoc,1394                                                 SourceLocation LParenLoc,1395                                                 SourceLocation ProtoIdLoc,1396                                                 SourceLocation RParenLoc) {1397  ASTContext &Context = getASTContext();1398  ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId, ProtoIdLoc);1399  if (!PDecl) {1400    Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;1401    return true;1402  }1403  if (PDecl->isNonRuntimeProtocol())1404    Diag(ProtoLoc, diag::err_objc_non_runtime_protocol_in_protocol_expr)1405        << PDecl;1406  if (!PDecl->hasDefinition()) {1407    Diag(ProtoLoc, diag::err_atprotocol_protocol) << PDecl;1408    Diag(PDecl->getLocation(), diag::note_entity_declared_at) << PDecl;1409  } else {1410    PDecl = PDecl->getDefinition();1411  }1412 1413  QualType Ty = Context.getObjCProtoType();1414  if (Ty.isNull())1415    return true;1416  Ty = Context.getObjCObjectPointerType(Ty);1417  return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, ProtoIdLoc, RParenLoc);1418}1419 1420/// Try to capture an implicit reference to 'self'.1421ObjCMethodDecl *SemaObjC::tryCaptureObjCSelf(SourceLocation Loc) {1422  DeclContext *DC = SemaRef.getFunctionLevelDeclContext();1423 1424  // If we're not in an ObjC method, error out.  Note that, unlike the1425  // C++ case, we don't require an instance method --- class methods1426  // still have a 'self', and we really do still need to capture it!1427  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(DC);1428  if (!method)1429    return nullptr;1430 1431  SemaRef.tryCaptureVariable(method->getSelfDecl(), Loc);1432 1433  return method;1434}1435 1436static QualType stripObjCInstanceType(ASTContext &Context, QualType T) {1437  QualType origType = T;1438  if (auto nullability = AttributedType::stripOuterNullability(T)) {1439    if (T == Context.getObjCInstanceType()) {1440      return Context.getAttributedType(*nullability, Context.getObjCIdType(),1441                                       Context.getObjCIdType());1442    }1443 1444    return origType;1445  }1446 1447  if (T == Context.getObjCInstanceType())1448    return Context.getObjCIdType();1449 1450  return origType;1451}1452 1453/// Determine the result type of a message send based on the receiver type,1454/// method, and the kind of message send.1455///1456/// This is the "base" result type, which will still need to be adjusted1457/// to account for nullability.1458static QualType getBaseMessageSendResultType(Sema &S,1459                                             QualType ReceiverType,1460                                             ObjCMethodDecl *Method,1461                                             bool isClassMessage,1462                                             bool isSuperMessage) {1463  assert(Method && "Must have a method");1464  if (!Method->hasRelatedResultType())1465    return Method->getSendResultType(ReceiverType);1466 1467  ASTContext &Context = S.Context;1468 1469  // Local function that transfers the nullability of the method's1470  // result type to the returned result.1471  auto transferNullability = [&](QualType type) -> QualType {1472    // If the method's result type has nullability, extract it.1473    if (auto nullability =1474            Method->getSendResultType(ReceiverType)->getNullability()) {1475      // Strip off any outer nullability sugar from the provided type.1476      (void)AttributedType::stripOuterNullability(type);1477 1478      // Form a new attributed type using the method result type's nullability.1479      return Context.getAttributedType(*nullability, type, type);1480    }1481 1482    return type;1483  };1484 1485  // If a method has a related return type:1486  //   - if the method found is an instance method, but the message send1487  //     was a class message send, T is the declared return type of the method1488  //     found1489  if (Method->isInstanceMethod() && isClassMessage)1490    return stripObjCInstanceType(Context,1491                                 Method->getSendResultType(ReceiverType));1492 1493  //   - if the receiver is super, T is a pointer to the class of the1494  //     enclosing method definition1495  if (isSuperMessage) {1496    if (ObjCMethodDecl *CurMethod = S.getCurMethodDecl())1497      if (ObjCInterfaceDecl *Class = CurMethod->getClassInterface()) {1498        return transferNullability(1499                 Context.getObjCObjectPointerType(1500                   Context.getObjCInterfaceType(Class)));1501      }1502  }1503 1504  //   - if the receiver is the name of a class U, T is a pointer to U1505  if (ReceiverType->getAsObjCInterfaceType())1506    return transferNullability(Context.getObjCObjectPointerType(ReceiverType));1507  //   - if the receiver is of type Class or qualified Class type,1508  //     T is the declared return type of the method.1509  if (ReceiverType->isObjCClassType() ||1510      ReceiverType->isObjCQualifiedClassType())1511    return stripObjCInstanceType(Context,1512                                 Method->getSendResultType(ReceiverType));1513 1514  //   - if the receiver is id, qualified id, Class, or qualified Class, T1515  //     is the receiver type, otherwise1516  //   - T is the type of the receiver expression.1517  return transferNullability(ReceiverType);1518}1519 1520QualType SemaObjC::getMessageSendResultType(const Expr *Receiver,1521                                            QualType ReceiverType,1522                                            ObjCMethodDecl *Method,1523                                            bool isClassMessage,1524                                            bool isSuperMessage) {1525  ASTContext &Context = getASTContext();1526  // Produce the result type.1527  QualType resultType = getBaseMessageSendResultType(1528      SemaRef, ReceiverType, Method, isClassMessage, isSuperMessage);1529 1530  // If this is a class message, ignore the nullability of the receiver.1531  if (isClassMessage) {1532    // In a class method, class messages to 'self' that return instancetype can1533    // be typed as the current class.  We can safely do this in ARC because self1534    // can't be reassigned, and we do it unsafely outside of ARC because in1535    // practice people never reassign self in class methods and there's some1536    // virtue in not being aggressively pedantic.1537    if (Receiver && Receiver->isObjCSelfExpr()) {1538      assert(ReceiverType->isObjCClassType() && "expected a Class self");1539      QualType T = Method->getSendResultType(ReceiverType);1540      AttributedType::stripOuterNullability(T);1541      if (T == Context.getObjCInstanceType()) {1542        const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(1543            cast<ImplicitParamDecl>(1544                cast<DeclRefExpr>(Receiver->IgnoreParenImpCasts())->getDecl())1545                ->getDeclContext());1546        assert(MD->isClassMethod() && "expected a class method");1547        QualType NewResultType = Context.getObjCObjectPointerType(1548            Context.getObjCInterfaceType(MD->getClassInterface()));1549        if (auto Nullability = resultType->getNullability())1550          NewResultType = Context.getAttributedType(*Nullability, NewResultType,1551                                                    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 nullability1559  // 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 nullability1581  // 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    Unspecified1588    /* 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 newResultNullabilityIdx1595    = nullabilityMap[receiverNullabilityIdx][resultNullabilityIdx];1596  if (newResultNullabilityIdx == resultNullabilityIdx)1597    return resultType;1598 1599  // Strip off the existing nullability. This removes as little type sugar as1600  // 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 newNullability1612      = static_cast<NullabilityKind>(newResultNullabilityIdx-1);1613    return Context.getAttributedType(newNullability, resultType, resultType);1614  }1615 1616  return resultType;1617}1618 1619/// Look for an ObjC method whose result type exactly matches the given type.1620static const ObjCMethodDecl *1621findExplicitInstancetypeDeclarer(const ObjCMethodDecl *MD,1622                                 QualType instancetype) {1623  if (MD->getReturnType() == instancetype)1624    return MD;1625 1626  // For these purposes, a method in an @implementation overrides a1627  // declaration in the @interface.1628  if (const ObjCImplDecl *impl =1629        dyn_cast<ObjCImplDecl>(MD->getDeclContext())) {1630    const ObjCContainerDecl *iface;1631    if (const ObjCCategoryImplDecl *catImpl =1632          dyn_cast<ObjCCategoryImplDecl>(impl)) {1633      iface = catImpl->getCategoryDecl();1634    } else {1635      iface = impl->getClassInterface();1636    }1637 1638    const ObjCMethodDecl *ifaceMD =1639      iface->getMethod(MD->getSelector(), MD->isInstanceMethod());1640    if (ifaceMD) return findExplicitInstancetypeDeclarer(ifaceMD, instancetype);1641  }1642 1643  SmallVector<const ObjCMethodDecl *, 4> overrides;1644  MD->getOverriddenMethods(overrides);1645  for (unsigned i = 0, e = overrides.size(); i != e; ++i) {1646    if (const ObjCMethodDecl *result =1647          findExplicitInstancetypeDeclarer(overrides[i], instancetype))1648      return result;1649  }1650 1651  return nullptr;1652}1653 1654void SemaObjC::EmitRelatedResultTypeNoteForReturn(QualType destType) {1655  ASTContext &Context = getASTContext();1656  // Only complain if we're in an ObjC method and the required return1657  // type doesn't match the method's declared return type.1658  ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext);1659  if (!MD || !MD->hasRelatedResultType() ||1660      Context.hasSameUnqualifiedType(destType, MD->getReturnType()))1661    return;1662 1663  // Look for a method overridden by this method which explicitly uses1664  // 'instancetype'.1665  if (const ObjCMethodDecl *overridden =1666        findExplicitInstancetypeDeclarer(MD, Context.getObjCInstanceType())) {1667    SourceRange range = overridden->getReturnTypeSourceRange();1668    SourceLocation loc = range.getBegin();1669    if (loc.isInvalid())1670      loc = overridden->getLocation();1671    Diag(loc, diag::note_related_result_type_explicit)1672      << /*current method*/ 1 << range;1673    return;1674  }1675 1676  // Otherwise, if we have an interesting method family, note that.1677  // This should always trigger if the above didn't.1678  if (ObjCMethodFamily family = MD->getMethodFamily())1679    Diag(MD->getLocation(), diag::note_related_result_type_family)1680      << /*current method*/ 11681      << family;1682}1683 1684void SemaObjC::EmitRelatedResultTypeNote(const Expr *E) {1685  ASTContext &Context = getASTContext();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 1698  if (Context.hasSameUnqualifiedType(1699          Method->getReturnType().getNonReferenceType(), MsgSend->getType()))1700    return;1701 1702  if (!Context.hasSameUnqualifiedType(Method->getReturnType(),1703                                      Context.getObjCInstanceType()))1704    return;1705 1706  Diag(Method->getLocation(), diag::note_related_result_type_inferred)1707    << Method->isInstanceMethod() << Method->getSelector()1708    << MsgSend->getType();1709}1710 1711bool SemaObjC::CheckMessageArgumentTypes(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  ASTContext &Context = getASTContext();1718  SourceLocation SelLoc;1719  if (!SelectorLocs.empty() && SelectorLocs.front().isValid())1720    SelLoc = SelectorLocs.front();1721  else1722    SelLoc = lbrac;1723 1724  if (!Method) {1725    // Apply default argument promotion as for (C99 6.5.2.2p6).1726    for (unsigned i = 0, e = Args.size(); i != e; i++) {1727      if (Args[i]->isTypeDependent())1728        continue;1729 1730      ExprResult result;1731      if (getLangOpts().DebuggerSupport) {1732        QualType paramTy; // ignored1733        result = SemaRef.checkUnknownAnyArg(SelLoc, Args[i], paramTy);1734      } else {1735        result = SemaRef.DefaultArgumentPromotion(Args[i]);1736      }1737      if (result.isInvalid())1738        return true;1739      Args[i] = result.get();1740    }1741 1742    unsigned DiagID;1743    if (getLangOpts().ObjCAutoRefCount)1744      DiagID = diag::err_arc_method_not_found;1745    else1746      DiagID = isClassMessage ? diag::warn_class_method_not_found1747                              : diag::warn_inst_method_not_found;1748    if (!getLangOpts().DebuggerSupport) {1749      const ObjCMethodDecl *OMD = SelectorsForTypoCorrection(Sel, ReceiverType);1750      if (OMD && !OMD->isInvalidDecl()) {1751        if (getLangOpts().ObjCAutoRefCount)1752          DiagID = diag::err_method_not_found_with_typo;1753        else1754          DiagID = isClassMessage ? diag::warn_class_method_not_found_with_typo1755                                  : diag::warn_instance_method_not_found_with_typo;1756        Selector MatchedSel = OMD->getSelector();1757        SourceRange SelectorRange(SelectorLocs.front(), SelectorLocs.back());1758        if (MatchedSel.isUnarySelector())1759          Diag(SelLoc, DiagID)1760            << Sel<< isClassMessage << MatchedSel1761            << FixItHint::CreateReplacement(SelectorRange, MatchedSel.getAsString());1762        else1763          Diag(SelLoc, DiagID) << Sel<< isClassMessage << MatchedSel;1764      }1765      else1766        Diag(SelLoc, DiagID)1767          << Sel << isClassMessage << SourceRange(SelectorLocs.front(),1768                                                SelectorLocs.back());1769      // Find the class to which we are sending this message.1770      if (auto *ObjPT = ReceiverType->getAs<ObjCObjectPointerType>()) {1771        if (ObjCInterfaceDecl *ThisClass = ObjPT->getInterfaceDecl()) {1772          Diag(ThisClass->getLocation(), diag::note_receiver_class_declared);1773          if (!RecRange.isInvalid())1774            if (ThisClass->lookupClassMethod(Sel))1775              Diag(RecRange.getBegin(), diag::note_receiver_expr_here)1776                  << FixItHint::CreateReplacement(RecRange,1777                                                  ThisClass->getNameAsString());1778        }1779      }1780    }1781 1782    // In debuggers, we want to use __unknown_anytype for these1783    // results so that clients can cast them.1784    if (getLangOpts().DebuggerSupport) {1785      ReturnType = Context.UnknownAnyTy;1786    } else {1787      ReturnType = Context.getObjCIdType();1788    }1789    VK = VK_PRValue;1790    return false;1791  }1792 1793  ReturnType = getMessageSendResultType(Receiver, ReceiverType, Method,1794                                        isClassMessage, isSuperMessage);1795  VK = Expr::getValueKindForType(Method->getReturnType());1796 1797  unsigned NumNamedArgs = Sel.getNumArgs();1798  // Method might have more arguments than selector indicates. This is due1799  // to addition of c-style arguments in method.1800  if (Method->param_size() > Sel.getNumArgs())1801    NumNamedArgs = Method->param_size();1802  // FIXME. This need be cleaned up.1803  if (Args.size() < NumNamedArgs) {1804    Diag(SelLoc, diag::err_typecheck_call_too_few_args)1805        << 2 << NumNamedArgs << static_cast<unsigned>(Args.size())1806        << /*is non object*/ 0;1807    return false;1808  }1809 1810  // Compute the set of type arguments to be substituted into each parameter1811  // type.1812  std::optional<ArrayRef<QualType>> typeArgs =1813      ReceiverType->getObjCSubstitutions(Method->getDeclContext());1814  bool IsError = false;1815  for (unsigned i = 0; i < NumNamedArgs; i++) {1816    // We can't do any type-checking on a type-dependent argument.1817    if (Args[i]->isTypeDependent())1818      continue;1819 1820    Expr *argExpr = Args[i];1821 1822    ParmVarDecl *param = Method->parameters()[i];1823    assert(argExpr && "CheckMessageArgumentTypes(): missing expression");1824 1825    if (param->hasAttr<NoEscapeAttr>() &&1826        param->getType()->isBlockPointerType())1827      if (auto *BE = dyn_cast<BlockExpr>(1828              argExpr->IgnoreParenNoopCasts(Context)))1829        BE->getBlockDecl()->setDoesNotEscape();1830 1831    // Strip the unbridged-cast placeholder expression off unless it's1832    // a consumed argument.1833    if (argExpr->hasPlaceholderType(BuiltinType::ARCUnbridgedCast) &&1834        !param->hasAttr<CFConsumedAttr>())1835      argExpr = stripARCUnbridgedCast(argExpr);1836 1837    // If the parameter is __unknown_anytype, infer its type1838    // from the argument.1839    if (param->getType() == Context.UnknownAnyTy) {1840      QualType paramType;1841      ExprResult argE = SemaRef.checkUnknownAnyArg(SelLoc, argExpr, paramType);1842      if (argE.isInvalid()) {1843        IsError = true;1844      } else {1845        Args[i] = argE.get();1846 1847        // Update the parameter type in-place.1848        param->setType(paramType);1849      }1850      continue;1851    }1852 1853    QualType origParamType = param->getType();1854    QualType paramType = param->getType();1855    if (typeArgs)1856      paramType = paramType.substObjCTypeArgs(1857                    Context,1858                    *typeArgs,1859                    ObjCSubstitutionContext::Parameter);1860 1861    if (SemaRef.RequireCompleteType(1862            argExpr->getSourceRange().getBegin(), paramType,1863            diag::err_call_incomplete_argument, argExpr))1864      return true;1865 1866    InitializedEntity Entity1867      = InitializedEntity::InitializeParameter(Context, param, paramType);1868    ExprResult ArgE =1869        SemaRef.PerformCopyInitialization(Entity, SourceLocation(), argExpr);1870    if (ArgE.isInvalid())1871      IsError = true;1872    else {1873      Args[i] = ArgE.getAs<Expr>();1874 1875      // If we are type-erasing a block to a block-compatible1876      // Objective-C pointer type, we may need to extend the lifetime1877      // of the block object.1878      if (typeArgs && Args[i]->isPRValue() && paramType->isBlockPointerType() &&1879          Args[i]->getType()->isBlockPointerType() &&1880          origParamType->isObjCObjectPointerType()) {1881        ExprResult arg = Args[i];1882        SemaRef.maybeExtendBlockObject(arg);1883        Args[i] = arg.get();1884      }1885    }1886  }1887 1888  // Promote additional arguments to variadic methods.1889  if (Method->isVariadic()) {1890    for (unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) {1891      if (Args[i]->isTypeDependent())1892        continue;1893 1894      ExprResult Arg = SemaRef.DefaultVariadicArgumentPromotion(1895          Args[i], VariadicCallType::Method, nullptr);1896      IsError |= Arg.isInvalid();1897      Args[i] = Arg.get();1898    }1899  } else {1900    // Check for extra arguments to non-variadic methods.1901    if (Args.size() != NumNamedArgs) {1902      Diag(Args[NumNamedArgs]->getBeginLoc(),1903           diag::err_typecheck_call_too_many_args)1904          << 2 /*method*/ << NumNamedArgs << static_cast<unsigned>(Args.size())1905          << Method->getSourceRange() << /*is non object*/ 01906          << SourceRange(Args[NumNamedArgs]->getBeginLoc(),1907                         Args.back()->getEndLoc());1908    }1909  }1910 1911  SemaRef.DiagnoseSentinelCalls(Method, SelLoc, Args);1912 1913  // Do additional checkings on method.1914  IsError |=1915      CheckObjCMethodCall(Method, SelLoc, ArrayRef(Args.data(), Args.size()));1916 1917  return IsError;1918}1919 1920bool SemaObjC::isSelfExpr(Expr *RExpr) {1921  // 'self' is objc 'self' in an objc method only.1922  ObjCMethodDecl *Method = dyn_cast_or_null<ObjCMethodDecl>(1923      SemaRef.CurContext->getNonClosureAncestor());1924  return isSelfExpr(RExpr, Method);1925}1926 1927bool SemaObjC::isSelfExpr(Expr *receiver, const ObjCMethodDecl *method) {1928  if (!method) return false;1929 1930  receiver = receiver->IgnoreParenLValueCasts();1931  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(receiver))1932    if (DRE->getDecl() == method->getSelfDecl())1933      return true;1934  return false;1935}1936 1937/// LookupMethodInType - Look up a method in an ObjCObjectType.1938ObjCMethodDecl *SemaObjC::LookupMethodInObjectType(Selector sel, QualType type,1939                                                   bool isInstance) {1940  const ObjCObjectType *objType = type->castAs<ObjCObjectType>();1941  if (ObjCInterfaceDecl *iface = objType->getInterface()) {1942    // Look it up in the main interface (and categories, etc.)1943    if (ObjCMethodDecl *method = iface->lookupMethod(sel, isInstance))1944      return method;1945 1946    // Okay, look for "private" methods declared in any1947    // @implementations we've seen.1948    if (ObjCMethodDecl *method = iface->lookupPrivateMethod(sel, isInstance))1949      return method;1950  }1951 1952  // Check qualifiers.1953  for (const auto *I : objType->quals())1954    if (ObjCMethodDecl *method = I->lookupMethod(sel, isInstance))1955      return method;1956 1957  return nullptr;1958}1959 1960/// LookupMethodInQualifiedType - Lookups up a method in protocol qualifier1961/// list of a qualified objective pointer type.1962ObjCMethodDecl *SemaObjC::LookupMethodInQualifiedType(1963    Selector Sel, const ObjCObjectPointerType *OPT, bool Instance) {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 an1974/// objective C interface.  This is a property reference expression.1975ExprResult SemaObjC::HandleExprPropertyRefExpr(1976    const ObjCObjectPointerType *OPT, Expr *BaseExpr, SourceLocation OpLoc,1977    DeclarationName MemberName, SourceLocation MemberLoc,1978    SourceLocation SuperLoc, QualType SuperType, bool Super) {1979  ASTContext &Context = getASTContext();1980  const ObjCInterfaceType *IFaceT = OPT->getInterfaceType();1981  assert(IFaceT && "Expected an Interface");1982  ObjCInterfaceDecl *IFace = IFaceT->getDecl();1983 1984  if (!MemberName.isIdentifier()) {1985    Diag(MemberLoc, diag::err_invalid_property_name)1986      << MemberName << QualType(OPT, 0);1987    return ExprError();1988  }1989 1990  IdentifierInfo *Member = MemberName.getAsIdentifierInfo();1991 1992  SourceRange BaseRange = Super? SourceRange(SuperLoc)1993                               : BaseExpr->getSourceRange();1994  if (SemaRef.RequireCompleteType(MemberLoc, OPT->getPointeeType(),1995                                  diag::err_property_not_found_forward_class,1996                                  MemberName, BaseRange))1997    return ExprError();1998 1999  if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(2000          Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {2001    // Check whether we can reference this property.2002    if (SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))2003      return ExprError();2004    if (Super)2005      return new (Context)2006          ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,2007                              OK_ObjCProperty, MemberLoc, SuperLoc, SuperType);2008    else2009      return new (Context)2010          ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,2011                              OK_ObjCProperty, MemberLoc, BaseExpr);2012  }2013  // Check protocols on qualified interfaces.2014  for (const auto *I : OPT->quals())2015    if (ObjCPropertyDecl *PD = I->FindPropertyDeclaration(2016            Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {2017      // Check whether we can reference this property.2018      if (SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))2019        return ExprError();2020 2021      if (Super)2022        return new (Context) ObjCPropertyRefExpr(2023            PD, Context.PseudoObjectTy, VK_LValue, OK_ObjCProperty, MemberLoc,2024            SuperLoc, SuperType);2025      else2026        return new (Context)2027            ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,2028                                OK_ObjCProperty, MemberLoc, BaseExpr);2029    }2030  // If that failed, look for an "implicit" property by seeing if the nullary2031  // selector is implemented.2032 2033  // FIXME: The logic for looking up nullary and unary selectors should be2034  // shared with the code in ActOnInstanceMessage.2035 2036  Selector Sel = SemaRef.PP.getSelectorTable().getNullarySelector(Member);2037  ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);2038 2039  // May be found in property's qualified list.2040  if (!Getter)2041    Getter = LookupMethodInQualifiedType(Sel, OPT, true);2042 2043  // If this reference is in an @implementation, check for 'private' methods.2044  if (!Getter)2045    Getter = IFace->lookupPrivateMethod(Sel);2046 2047  if (Getter) {2048    // Check if we can reference this property.2049    if (SemaRef.DiagnoseUseOfDecl(Getter, MemberLoc))2050      return ExprError();2051  }2052  // If we found a getter then this may be a valid dot-reference, we2053  // will look for the matching setter, in case it is needed.2054  Selector SetterSel = SelectorTable::constructSetterSelector(2055      SemaRef.PP.getIdentifierTable(), SemaRef.PP.getSelectorTable(), Member);2056  ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);2057 2058  // May be found in property's qualified list.2059  if (!Setter)2060    Setter = LookupMethodInQualifiedType(SetterSel, OPT, true);2061 2062  if (!Setter) {2063    // If this reference is in an @implementation, also check for 'private'2064    // methods.2065    Setter = IFace->lookupPrivateMethod(SetterSel);2066  }2067 2068  if (Setter && SemaRef.DiagnoseUseOfDecl(Setter, MemberLoc))2069    return ExprError();2070 2071  // Special warning if member name used in a property-dot for a setter accessor2072  // does not use a property with same name; e.g. obj.X = ... for a property with2073  // name 'x'.2074  if (Setter && Setter->isImplicit() && Setter->isPropertyAccessor() &&2075      !IFace->FindPropertyDeclaration(2076          Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {2077      if (const ObjCPropertyDecl *PDecl = Setter->findPropertyDecl()) {2078        // Do not warn if user is using property-dot syntax to make call to2079        // user named setter.2080        if (!(PDecl->getPropertyAttributes() &2081              ObjCPropertyAttribute::kind_setter))2082          Diag(MemberLoc,2083               diag::warn_property_access_suggest)2084          << MemberName << QualType(OPT, 0) << PDecl->getName()2085          << FixItHint::CreateReplacement(MemberLoc, PDecl->getName());2086      }2087  }2088 2089  if (Getter || Setter) {2090    if (Super)2091      return new (Context)2092          ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,2093                              OK_ObjCProperty, MemberLoc, SuperLoc, SuperType);2094    else2095      return new (Context)2096          ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,2097                              OK_ObjCProperty, MemberLoc, BaseExpr);2098 2099  }2100 2101  // Attempt to correct for typos in property names.2102  DeclFilterCCC<ObjCPropertyDecl> CCC{};2103  if (TypoCorrection Corrected = SemaRef.CorrectTypo(2104          DeclarationNameInfo(MemberName, MemberLoc), Sema::LookupOrdinaryName,2105          nullptr, nullptr, CCC, CorrectTypoKind::ErrorRecovery, IFace, false,2106          OPT)) {2107    DeclarationName TypoResult = Corrected.getCorrection();2108    if (TypoResult.isIdentifier() &&2109        TypoResult.getAsIdentifierInfo() == Member) {2110      // There is no need to try the correction if it is the same.2111      NamedDecl *ChosenDecl =2112        Corrected.isKeyword() ? nullptr : Corrected.getFoundDecl();2113      if (ChosenDecl && isa<ObjCPropertyDecl>(ChosenDecl))2114        if (cast<ObjCPropertyDecl>(ChosenDecl)->isClassProperty()) {2115          // This is a class property, we should not use the instance to2116          // access it.2117          Diag(MemberLoc, diag::err_class_property_found) << MemberName2118          << OPT->getInterfaceDecl()->getName()2119          << FixItHint::CreateReplacement(BaseExpr->getSourceRange(),2120                                          OPT->getInterfaceDecl()->getName());2121          return ExprError();2122        }2123    } else {2124      SemaRef.diagnoseTypo(Corrected,2125                           PDiag(diag::err_property_not_found_suggest)2126                               << MemberName << QualType(OPT, 0));2127      return HandleExprPropertyRefExpr(OPT, BaseExpr, OpLoc,2128                                       TypoResult, MemberLoc,2129                                       SuperLoc, SuperType, Super);2130    }2131  }2132  ObjCInterfaceDecl *ClassDeclared;2133  if (ObjCIvarDecl *Ivar =2134      IFace->lookupInstanceVariable(Member, ClassDeclared)) {2135    QualType T = Ivar->getType();2136    if (const ObjCObjectPointerType * OBJPT =2137        T->getAsObjCInterfacePointerType()) {2138      if (SemaRef.RequireCompleteType(MemberLoc, OBJPT->getPointeeType(),2139                                      diag::err_property_not_as_forward_class,2140                                      MemberName, BaseExpr))2141        return ExprError();2142    }2143    Diag(MemberLoc,2144         diag::err_ivar_access_using_property_syntax_suggest)2145    << MemberName << QualType(OPT, 0) << Ivar->getDeclName()2146    << FixItHint::CreateReplacement(OpLoc, "->");2147    return ExprError();2148  }2149 2150  Diag(MemberLoc, diag::err_property_not_found)2151    << MemberName << QualType(OPT, 0);2152  if (Setter)2153    Diag(Setter->getLocation(), diag::note_getter_unavailable)2154          << MemberName << BaseExpr->getSourceRange();2155  return ExprError();2156}2157 2158ExprResult SemaObjC::ActOnClassPropertyRefExpr(2159    const IdentifierInfo &receiverName, const IdentifierInfo &propertyName,2160    SourceLocation receiverNameLoc, SourceLocation propertyNameLoc) {2161  ASTContext &Context = getASTContext();2162  const IdentifierInfo *receiverNamePtr = &receiverName;2163  ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(receiverNamePtr,2164                                                  receiverNameLoc);2165 2166  QualType SuperType;2167  if (!IFace) {2168    // If the "receiver" is 'super' in a method, handle it as an expression-like2169    // property reference.2170    if (receiverNamePtr->isStr("super")) {2171      if (ObjCMethodDecl *CurMethod = tryCaptureObjCSelf(receiverNameLoc)) {2172        if (auto classDecl = CurMethod->getClassInterface()) {2173          SuperType = QualType(classDecl->getSuperClassType(), 0);2174          if (CurMethod->isInstanceMethod()) {2175            if (SuperType.isNull()) {2176              // The current class does not have a superclass.2177              Diag(receiverNameLoc, diag::err_root_class_cannot_use_super)2178                << CurMethod->getClassInterface()->getIdentifier();2179              return ExprError();2180            }2181            QualType T = Context.getObjCObjectPointerType(SuperType);2182 2183            return HandleExprPropertyRefExpr(T->castAs<ObjCObjectPointerType>(),2184                                             /*BaseExpr*/nullptr,2185                                             SourceLocation()/*OpLoc*/,2186                                             &propertyName,2187                                             propertyNameLoc,2188                                             receiverNameLoc, T, true);2189          }2190 2191          // Otherwise, if this is a class method, try dispatching to our2192          // superclass.2193          IFace = CurMethod->getClassInterface()->getSuperClass();2194        }2195      }2196    }2197 2198    if (!IFace) {2199      Diag(receiverNameLoc, diag::err_expected_either) << tok::identifier2200                                                       << tok::l_paren;2201      return ExprError();2202    }2203  }2204 2205  Selector GetterSel;2206  Selector SetterSel;2207  if (auto PD = IFace->FindPropertyDeclaration(2208          &propertyName, ObjCPropertyQueryKind::OBJC_PR_query_class)) {2209    GetterSel = PD->getGetterName();2210    SetterSel = PD->getSetterName();2211  } else {2212    GetterSel = SemaRef.PP.getSelectorTable().getNullarySelector(&propertyName);2213    SetterSel = SelectorTable::constructSetterSelector(2214        SemaRef.PP.getIdentifierTable(), SemaRef.PP.getSelectorTable(),2215        &propertyName);2216  }2217 2218  // Search for a declared property first.2219  ObjCMethodDecl *Getter = IFace->lookupClassMethod(GetterSel);2220 2221  // If this reference is in an @implementation, check for 'private' methods.2222  if (!Getter)2223    Getter = IFace->lookupPrivateClassMethod(GetterSel);2224 2225  if (Getter) {2226    // FIXME: refactor/share with ActOnMemberReference().2227    // Check if we can reference this property.2228    if (SemaRef.DiagnoseUseOfDecl(Getter, propertyNameLoc))2229      return ExprError();2230  }2231 2232  // Look for the matching setter, in case it is needed.2233  ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);2234  if (!Setter) {2235    // If this reference is in an @implementation, also check for 'private'2236    // methods.2237    Setter = IFace->lookupPrivateClassMethod(SetterSel);2238  }2239  // Look through local category implementations associated with the class.2240  if (!Setter)2241    Setter = IFace->getCategoryClassMethod(SetterSel);2242 2243  if (Setter && SemaRef.DiagnoseUseOfDecl(Setter, propertyNameLoc))2244    return ExprError();2245 2246  if (Getter || Setter) {2247    if (!SuperType.isNull())2248      return new (Context)2249          ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,2250                              OK_ObjCProperty, propertyNameLoc, receiverNameLoc,2251                              SuperType);2252 2253    return new (Context) ObjCPropertyRefExpr(2254        Getter, Setter, Context.PseudoObjectTy, VK_LValue, OK_ObjCProperty,2255        propertyNameLoc, receiverNameLoc, IFace);2256  }2257  return ExprError(Diag(propertyNameLoc, diag::err_property_not_found)2258                     << &propertyName << Context.getObjCInterfaceType(IFace));2259}2260 2261namespace {2262 2263class ObjCInterfaceOrSuperCCC final : public CorrectionCandidateCallback {2264 public:2265  ObjCInterfaceOrSuperCCC(ObjCMethodDecl *Method) {2266    // Determine whether "super" is acceptable in the current context.2267    if (Method && Method->getClassInterface())2268      WantObjCSuper = Method->getClassInterface()->getSuperClass();2269  }2270 2271  bool ValidateCandidate(const TypoCorrection &candidate) override {2272    return candidate.getCorrectionDeclAs<ObjCInterfaceDecl>() ||2273        candidate.isKeyword("super");2274  }2275 2276  std::unique_ptr<CorrectionCandidateCallback> clone() override {2277    return std::make_unique<ObjCInterfaceOrSuperCCC>(*this);2278  }2279};2280 2281} // end anonymous namespace2282 2283SemaObjC::ObjCMessageKind2284SemaObjC::getObjCMessageKind(Scope *S, IdentifierInfo *Name,2285                             SourceLocation NameLoc, bool IsSuper,2286                             bool HasTrailingDot, ParsedType &ReceiverType) {2287  ASTContext &Context = getASTContext();2288  ReceiverType = nullptr;2289 2290  // If the identifier is "super" and there is no trailing dot, we're2291  // messaging super. If the identifier is "super" and there is a2292  // trailing dot, it's an instance message.2293  if (IsSuper && S->isInObjcMethodScope())2294    return HasTrailingDot? ObjCInstanceMessage : ObjCSuperMessage;2295 2296  LookupResult Result(SemaRef, Name, NameLoc, Sema::LookupOrdinaryName);2297  SemaRef.LookupName(Result, S);2298 2299  switch (Result.getResultKind()) {2300  case LookupResultKind::NotFound:2301    // Normal name lookup didn't find anything. If we're in an2302    // Objective-C method, look for ivars. If we find one, we're done!2303    // FIXME: This is a hack. Ivar lookup should be part of normal2304    // lookup.2305    if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {2306      if (!Method->getClassInterface()) {2307        // Fall back: let the parser try to parse it as an instance message.2308        return ObjCInstanceMessage;2309      }2310 2311      ObjCInterfaceDecl *ClassDeclared;2312      if (Method->getClassInterface()->lookupInstanceVariable(Name,2313                                                              ClassDeclared))2314        return ObjCInstanceMessage;2315    }2316 2317    // Break out; we'll perform typo correction below.2318    break;2319 2320  case LookupResultKind::NotFoundInCurrentInstantiation:2321  case LookupResultKind::FoundOverloaded:2322  case LookupResultKind::FoundUnresolvedValue:2323  case LookupResultKind::Ambiguous:2324    Result.suppressDiagnostics();2325    return ObjCInstanceMessage;2326 2327  case LookupResultKind::Found: {2328    // If the identifier is a class or not, and there is a trailing dot,2329    // it's an instance message.2330    if (HasTrailingDot)2331      return ObjCInstanceMessage;2332    // We found something. If it's a type, then we have a class2333    // message. Otherwise, it's an instance message.2334    NamedDecl *ND = Result.getFoundDecl();2335    QualType T;2336    if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(ND))2337      T = Context.getObjCInterfaceType(Class);2338    else if (TypeDecl *Type = dyn_cast<TypeDecl>(ND)) {2339      SemaRef.DiagnoseUseOfDecl(Type, NameLoc);2340      T = Context.getTypeDeclType(ElaboratedTypeKeyword::None,2341                                  /*Qualifier=*/std::nullopt, Type);2342    } else2343      return ObjCInstanceMessage;2344 2345    //  We have a class message, and T is the type we're2346    //  messaging. Build source-location information for it.2347    TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);2348    ReceiverType = SemaRef.CreateParsedType(T, TSInfo);2349    return ObjCClassMessage;2350  }2351  }2352 2353  ObjCInterfaceOrSuperCCC CCC(SemaRef.getCurMethodDecl());2354  if (TypoCorrection Corrected = SemaRef.CorrectTypo(2355          Result.getLookupNameInfo(), Result.getLookupKind(), S, nullptr, CCC,2356          CorrectTypoKind::ErrorRecovery, nullptr, false, nullptr, false)) {2357    if (Corrected.isKeyword()) {2358      // If we've found the keyword "super" (the only keyword that would be2359      // returned by CorrectTypo), this is a send to super.2360      SemaRef.diagnoseTypo(Corrected, PDiag(diag::err_unknown_receiver_suggest)2361                                          << Name);2362      return ObjCSuperMessage;2363    } else if (ObjCInterfaceDecl *Class =2364                   Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) {2365      // If we found a declaration, correct when it refers to an Objective-C2366      // class.2367      SemaRef.diagnoseTypo(Corrected, PDiag(diag::err_unknown_receiver_suggest)2368                                          << Name);2369      QualType T = Context.getObjCInterfaceType(Class);2370      TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);2371      ReceiverType = SemaRef.CreateParsedType(T, TSInfo);2372      return ObjCClassMessage;2373    }2374  }2375 2376  // Fall back: let the parser try to parse it as an instance message.2377  return ObjCInstanceMessage;2378}2379 2380ExprResult SemaObjC::ActOnSuperMessage(Scope *S, SourceLocation SuperLoc,2381                                       Selector Sel, SourceLocation LBracLoc,2382                                       ArrayRef<SourceLocation> SelectorLocs,2383                                       SourceLocation RBracLoc,2384                                       MultiExprArg Args) {2385  ASTContext &Context = getASTContext();2386  // Determine whether we are inside a method or not.2387  ObjCMethodDecl *Method = tryCaptureObjCSelf(SuperLoc);2388  if (!Method) {2389    Diag(SuperLoc, diag::err_invalid_receiver_to_message_super);2390    return ExprError();2391  }2392 2393  ObjCInterfaceDecl *Class = Method->getClassInterface();2394  if (!Class) {2395    Diag(SuperLoc, diag::err_no_super_class_message)2396      << Method->getDeclName();2397    return ExprError();2398  }2399 2400  QualType SuperTy(Class->getSuperClassType(), 0);2401  if (SuperTy.isNull()) {2402    // The current class does not have a superclass.2403    Diag(SuperLoc, diag::err_root_class_cannot_use_super)2404      << Class->getIdentifier();2405    return ExprError();2406  }2407 2408  // We are in a method whose class has a superclass, so 'super'2409  // is acting as a keyword.2410  if (Method->getSelector() == Sel)2411    SemaRef.getCurFunction()->ObjCShouldCallSuper = false;2412 2413  if (Method->isInstanceMethod()) {2414    // Since we are in an instance method, this is an instance2415    // message to the superclass instance.2416    SuperTy = Context.getObjCObjectPointerType(SuperTy);2417    return BuildInstanceMessage(nullptr, SuperTy, SuperLoc,2418                                Sel, /*Method=*/nullptr,2419                                LBracLoc, SelectorLocs, RBracLoc, Args);2420  }2421 2422  // Since we are in a class method, this is a class message to2423  // the superclass.2424  return BuildClassMessage(/*ReceiverTypeInfo=*/nullptr,2425                           SuperTy,2426                           SuperLoc, Sel, /*Method=*/nullptr,2427                           LBracLoc, SelectorLocs, RBracLoc, Args);2428}2429 2430ExprResult SemaObjC::BuildClassMessageImplicit(QualType ReceiverType,2431                                               bool isSuperReceiver,2432                                               SourceLocation Loc, Selector Sel,2433                                               ObjCMethodDecl *Method,2434                                               MultiExprArg Args) {2435  ASTContext &Context = getASTContext();2436  TypeSourceInfo *receiverTypeInfo = nullptr;2437  if (!ReceiverType.isNull())2438    receiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType);2439 2440  assert(((isSuperReceiver && Loc.isValid()) || receiverTypeInfo) &&2441         "Either the super receiver location needs to be valid or the receiver "2442         "needs valid type source information");2443  return BuildClassMessage(receiverTypeInfo, ReceiverType,2444                          /*SuperLoc=*/isSuperReceiver ? Loc : SourceLocation(),2445                           Sel, Method, Loc, Loc, Loc, Args,2446                           /*isImplicit=*/true);2447}2448 2449static void applyCocoaAPICheck(Sema &S, const ObjCMessageExpr *Msg,2450                               unsigned DiagID,2451                               bool (*refactor)(const ObjCMessageExpr *,2452                                              const NSAPI &, edit::Commit &)) {2453  SourceLocation MsgLoc = Msg->getExprLoc();2454  if (S.Diags.isIgnored(DiagID, MsgLoc))2455    return;2456 2457  SourceManager &SM = S.SourceMgr;2458  edit::Commit ECommit(SM, S.LangOpts);2459  if (refactor(Msg, *S.ObjC().NSAPIObj, ECommit)) {2460    auto Builder = S.Diag(MsgLoc, DiagID)2461                   << Msg->getSelector() << Msg->getSourceRange();2462    // FIXME: Don't emit diagnostic at all if fixits are non-commitable.2463    if (!ECommit.isCommitable())2464      return;2465    for (edit::Commit::edit_iterator2466           I = ECommit.edit_begin(), E = ECommit.edit_end(); I != E; ++I) {2467      const edit::Commit::Edit &Edit = *I;2468      switch (Edit.Kind) {2469      case edit::Commit::Act_Insert:2470        Builder.AddFixItHint(FixItHint::CreateInsertion(Edit.OrigLoc,2471                                                        Edit.Text,2472                                                        Edit.BeforePrev));2473        break;2474      case edit::Commit::Act_InsertFromRange:2475        Builder.AddFixItHint(2476            FixItHint::CreateInsertionFromRange(Edit.OrigLoc,2477                                                Edit.getInsertFromRange(SM),2478                                                Edit.BeforePrev));2479        break;2480      case edit::Commit::Act_Remove:2481        Builder.AddFixItHint(FixItHint::CreateRemoval(Edit.getFileRange(SM)));2482        break;2483      }2484    }2485  }2486}2487 2488static void checkCocoaAPI(Sema &S, const ObjCMessageExpr *Msg) {2489  applyCocoaAPICheck(S, Msg, diag::warn_objc_redundant_literal_use,2490                     edit::rewriteObjCRedundantCallWithLiteral);2491}2492 2493static void checkFoundationAPI(Sema &S, SourceLocation Loc,2494                               const ObjCMethodDecl *Method,2495                               ArrayRef<Expr *> Args, QualType ReceiverType,2496                               bool IsClassObjectCall) {2497  // Check if this is a performSelector method that uses a selector that returns2498  // a record or a vector type.2499  if (Method->getSelector().getMethodFamily() != OMF_performSelector ||2500      Args.empty())2501    return;2502  const auto *SE = dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens());2503  if (!SE)2504    return;2505  ObjCMethodDecl *ImpliedMethod;2506  if (!IsClassObjectCall) {2507    const auto *OPT = ReceiverType->getAs<ObjCObjectPointerType>();2508    if (!OPT || !OPT->getInterfaceDecl())2509      return;2510    ImpliedMethod =2511        OPT->getInterfaceDecl()->lookupInstanceMethod(SE->getSelector());2512    if (!ImpliedMethod)2513      ImpliedMethod =2514          OPT->getInterfaceDecl()->lookupPrivateMethod(SE->getSelector());2515  } else {2516    const auto *IT = ReceiverType->getAs<ObjCInterfaceType>();2517    if (!IT)2518      return;2519    ImpliedMethod = IT->getDecl()->lookupClassMethod(SE->getSelector());2520    if (!ImpliedMethod)2521      ImpliedMethod =2522          IT->getDecl()->lookupPrivateClassMethod(SE->getSelector());2523  }2524  if (!ImpliedMethod)2525    return;2526  QualType Ret = ImpliedMethod->getReturnType();2527  if (Ret->isRecordType() || Ret->isVectorType() || Ret->isExtVectorType()) {2528    S.Diag(Loc, diag::warn_objc_unsafe_perform_selector)2529        << Method->getSelector()2530        << (!Ret->isRecordType()2531                ? /*Vector*/ 22532                : Ret->isUnionType() ? /*Union*/ 1 : /*Struct*/ 0);2533    S.Diag(ImpliedMethod->getBeginLoc(),2534           diag::note_objc_unsafe_perform_selector_method_declared_here)2535        << ImpliedMethod->getSelector() << Ret;2536  }2537}2538 2539/// Diagnose use of %s directive in an NSString which is being passed2540/// as formatting string to formatting method.2541static void2542DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S,2543                                        ObjCMethodDecl *Method,2544                                        Selector Sel,2545                                        Expr **Args, unsigned NumArgs) {2546  unsigned Idx = 0;2547  bool Format = false;2548  ObjCStringFormatFamily SFFamily = Sel.getStringFormatFamily();2549  if (SFFamily == ObjCStringFormatFamily::SFF_NSString) {2550    Idx = 0;2551    Format = true;2552  }2553  else if (Method) {2554    for (const auto *I : Method->specific_attrs<FormatAttr>()) {2555      if (S.ObjC().GetFormatNSStringIdx(I, Idx)) {2556        Format = true;2557        break;2558      }2559    }2560  }2561  if (!Format || NumArgs <= Idx)2562    return;2563 2564  Expr *FormatExpr = Args[Idx];2565  if (ObjCStringLiteral *OSL =2566      dyn_cast<ObjCStringLiteral>(FormatExpr->IgnoreParenImpCasts())) {2567    StringLiteral *FormatString = OSL->getString();2568    if (S.FormatStringHasSArg(FormatString)) {2569      S.Diag(FormatExpr->getExprLoc(), diag::warn_objc_cdirective_format_string)2570        << "%s" << 0 << 0;2571      if (Method)2572        S.Diag(Method->getLocation(), diag::note_method_declared_at)2573          << Method->getDeclName();2574    }2575  }2576}2577 2578/// Build an Objective-C class message expression.2579///2580/// This routine takes care of both normal class messages and2581/// class messages to the superclass.2582///2583/// \param ReceiverTypeInfo Type source information that describes the2584/// receiver of this message. This may be NULL, in which case we are2585/// sending to the superclass and \p SuperLoc must be a valid source2586/// location.2587 2588/// \param ReceiverType The type of the object receiving the2589/// message. When \p ReceiverTypeInfo is non-NULL, this is the same2590/// type as that refers to. For a superclass send, this is the type of2591/// the superclass.2592///2593/// \param SuperLoc The location of the "super" keyword in a2594/// superclass message.2595///2596/// \param Sel The selector to which the message is being sent.2597///2598/// \param Method The method that this class message is invoking, if2599/// already known.2600///2601/// \param LBracLoc The location of the opening square bracket ']'.2602///2603/// \param RBracLoc The location of the closing square bracket ']'.2604///2605/// \param ArgsIn The message arguments.2606ExprResult SemaObjC::BuildClassMessage(2607    TypeSourceInfo *ReceiverTypeInfo, QualType ReceiverType,2608    SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method,2609    SourceLocation LBracLoc, ArrayRef<SourceLocation> SelectorLocs,2610    SourceLocation RBracLoc, MultiExprArg ArgsIn, bool isImplicit) {2611  ASTContext &Context = getASTContext();2612  SourceLocation Loc = SuperLoc.isValid()? SuperLoc2613    : ReceiverTypeInfo->getTypeLoc().getSourceRange().getBegin();2614  if (LBracLoc.isInvalid()) {2615    Diag(Loc, diag::err_missing_open_square_message_send)2616      << FixItHint::CreateInsertion(Loc, "[");2617    LBracLoc = Loc;2618  }2619  ArrayRef<SourceLocation> SelectorSlotLocs;2620  if (!SelectorLocs.empty() && SelectorLocs.front().isValid())2621    SelectorSlotLocs = SelectorLocs;2622  else2623    SelectorSlotLocs = Loc;2624  SourceLocation SelLoc = SelectorSlotLocs.front();2625 2626  if (ReceiverType->isDependentType()) {2627    // If the receiver type is dependent, we can't type-check anything2628    // at this point. Build a dependent expression.2629    unsigned NumArgs = ArgsIn.size();2630    Expr **Args = ArgsIn.data();2631    assert(SuperLoc.isInvalid() && "Message to super with dependent type");2632    return ObjCMessageExpr::Create(Context, ReceiverType, VK_PRValue, LBracLoc,2633                                   ReceiverTypeInfo, Sel, SelectorLocs,2634                                   /*Method=*/nullptr, ArrayRef(Args, NumArgs),2635                                   RBracLoc, isImplicit);2636  }2637 2638  // Find the class to which we are sending this message.2639  ObjCInterfaceDecl *Class = nullptr;2640  const ObjCObjectType *ClassType = ReceiverType->getAs<ObjCObjectType>();2641  if (!ClassType || !(Class = ClassType->getInterface())) {2642    Diag(Loc, diag::err_invalid_receiver_class_message)2643      << ReceiverType;2644    return ExprError();2645  }2646  assert(Class && "We don't know which class we're messaging?");2647  // objc++ diagnoses during typename annotation.2648  if (!getLangOpts().CPlusPlus)2649    (void)SemaRef.DiagnoseUseOfDecl(Class, SelectorSlotLocs);2650  // Find the method we are messaging.2651  if (!Method) {2652    SourceRange TypeRange2653      = SuperLoc.isValid()? SourceRange(SuperLoc)2654                          : ReceiverTypeInfo->getTypeLoc().getSourceRange();2655    if (SemaRef.RequireCompleteType(Loc, Context.getObjCInterfaceType(Class),2656                                    (getLangOpts().ObjCAutoRefCount2657                                         ? diag::err_arc_receiver_forward_class2658                                         : diag::warn_receiver_forward_class),2659                                    TypeRange)) {2660      // A forward class used in messaging is treated as a 'Class'2661      Method = LookupFactoryMethodInGlobalPool(Sel,2662                                               SourceRange(LBracLoc, RBracLoc));2663      if (Method && !getLangOpts().ObjCAutoRefCount)2664        Diag(Method->getLocation(), diag::note_method_sent_forward_class)2665          << Method->getDeclName();2666    }2667    if (!Method)2668      Method = Class->lookupClassMethod(Sel);2669 2670    // If we have an implementation in scope, check "private" methods.2671    if (!Method)2672      Method = Class->lookupPrivateClassMethod(Sel);2673 2674    if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, nullptr,2675                                            false, false, Class))2676      return ExprError();2677  }2678 2679  // Check the argument types and determine the result type.2680  QualType ReturnType;2681  ExprValueKind VK = VK_PRValue;2682 2683  unsigned NumArgs = ArgsIn.size();2684  Expr **Args = ArgsIn.data();2685  if (CheckMessageArgumentTypes(/*Receiver=*/nullptr, ReceiverType,2686                                MultiExprArg(Args, NumArgs), Sel, SelectorLocs,2687                                Method, true, SuperLoc.isValid(), LBracLoc,2688                                RBracLoc, SourceRange(), ReturnType, VK))2689    return ExprError();2690 2691  if (Method && !Method->getReturnType()->isVoidType() &&2692      SemaRef.RequireCompleteType(2693          LBracLoc, Method->getReturnType(),2694          diag::err_illegal_message_expr_incomplete_type))2695    return ExprError();2696 2697  if (Method && Method->isDirectMethod() && SuperLoc.isValid()) {2698    Diag(SuperLoc, diag::err_messaging_super_with_direct_method)2699        << FixItHint::CreateReplacement(2700               SuperLoc, getLangOpts().ObjCAutoRefCount2701                             ? "self"2702                             : Method->getClassInterface()->getName());2703    Diag(Method->getLocation(), diag::note_direct_method_declared_at)2704        << Method->getDeclName();2705  }2706 2707  // Warn about explicit call of +initialize on its own class. But not on 'super'.2708  if (Method && Method->getMethodFamily() == OMF_initialize) {2709    if (!SuperLoc.isValid()) {2710      const ObjCInterfaceDecl *ID =2711        dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext());2712      if (ID == Class) {2713        Diag(Loc, diag::warn_direct_initialize_call);2714        Diag(Method->getLocation(), diag::note_method_declared_at)2715          << Method->getDeclName();2716      }2717    } else if (ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl()) {2718      // [super initialize] is allowed only within an +initialize implementation2719      if (CurMeth->getMethodFamily() != OMF_initialize) {2720        Diag(Loc, diag::warn_direct_super_initialize_call);2721        Diag(Method->getLocation(), diag::note_method_declared_at)2722          << Method->getDeclName();2723        Diag(CurMeth->getLocation(), diag::note_method_declared_at)2724        << CurMeth->getDeclName();2725      }2726    }2727  }2728 2729  DiagnoseCStringFormatDirectiveInObjCAPI(SemaRef, Method, Sel, Args, NumArgs);2730 2731  // Construct the appropriate ObjCMessageExpr.2732  ObjCMessageExpr *Result;2733  if (SuperLoc.isValid())2734    Result = ObjCMessageExpr::Create(2735        Context, ReturnType, VK, LBracLoc, SuperLoc, /*IsInstanceSuper=*/false,2736        ReceiverType, Sel, SelectorLocs, Method, ArrayRef(Args, NumArgs),2737        RBracLoc, isImplicit);2738  else {2739    Result = ObjCMessageExpr::Create(2740        Context, ReturnType, VK, LBracLoc, ReceiverTypeInfo, Sel, SelectorLocs,2741        Method, ArrayRef(Args, NumArgs), RBracLoc, isImplicit);2742    if (!isImplicit)2743      checkCocoaAPI(SemaRef, Result);2744  }2745  if (Method)2746    checkFoundationAPI(SemaRef, SelLoc, Method, ArrayRef(Args, NumArgs),2747                       ReceiverType, /*IsClassObjectCall=*/true);2748  return SemaRef.MaybeBindToTemporary(Result);2749}2750 2751// ActOnClassMessage - used for both unary and keyword messages.2752// ArgExprs is optional - if it is present, the number of expressions2753// is obtained from Sel.getNumArgs().2754ExprResult SemaObjC::ActOnClassMessage(Scope *S, ParsedType Receiver,2755                                       Selector Sel, SourceLocation LBracLoc,2756                                       ArrayRef<SourceLocation> SelectorLocs,2757                                       SourceLocation RBracLoc,2758                                       MultiExprArg Args) {2759  ASTContext &Context = getASTContext();2760  TypeSourceInfo *ReceiverTypeInfo;2761  QualType ReceiverType =2762      SemaRef.GetTypeFromParser(Receiver, &ReceiverTypeInfo);2763  if (ReceiverType.isNull())2764    return ExprError();2765 2766  if (!ReceiverTypeInfo)2767    ReceiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType, LBracLoc);2768 2769  return BuildClassMessage(ReceiverTypeInfo, ReceiverType,2770                           /*SuperLoc=*/SourceLocation(), Sel,2771                           /*Method=*/nullptr, LBracLoc, SelectorLocs, RBracLoc,2772                           Args);2773}2774 2775ExprResult SemaObjC::BuildInstanceMessageImplicit(2776    Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel,2777    ObjCMethodDecl *Method, MultiExprArg Args) {2778  return BuildInstanceMessage(Receiver, ReceiverType,2779                              /*SuperLoc=*/!Receiver ? Loc : SourceLocation(),2780                              Sel, Method, Loc, Loc, Loc, Args,2781                              /*isImplicit=*/true);2782}2783 2784static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M) {2785  if (!S.ObjC().NSAPIObj)2786    return false;2787  const auto *Protocol = dyn_cast<ObjCProtocolDecl>(M->getDeclContext());2788  if (!Protocol)2789    return false;2790  const IdentifierInfo *II =2791      S.ObjC().NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject);2792  if (const auto *RootClass = dyn_cast_or_null<ObjCInterfaceDecl>(2793          S.LookupSingleName(S.TUScope, II, Protocol->getBeginLoc(),2794                             Sema::LookupOrdinaryName))) {2795    for (const ObjCProtocolDecl *P : RootClass->all_referenced_protocols()) {2796      if (P->getCanonicalDecl() == Protocol->getCanonicalDecl())2797        return true;2798    }2799  }2800  return false;2801}2802 2803/// Build an Objective-C instance message expression.2804///2805/// This routine takes care of both normal instance messages and2806/// instance messages to the superclass instance.2807///2808/// \param Receiver The expression that computes the object that will2809/// receive this message. This may be empty, in which case we are2810/// sending to the superclass instance and \p SuperLoc must be a valid2811/// source location.2812///2813/// \param ReceiverType The (static) type of the object receiving the2814/// message. When a \p Receiver expression is provided, this is the2815/// same type as that expression. For a superclass instance send, this2816/// is a pointer to the type of the superclass.2817///2818/// \param SuperLoc The location of the "super" keyword in a2819/// superclass instance message.2820///2821/// \param Sel The selector to which the message is being sent.2822///2823/// \param Method The method that this instance message is invoking, if2824/// already known.2825///2826/// \param LBracLoc The location of the opening square bracket ']'.2827///2828/// \param RBracLoc The location of the closing square bracket ']'.2829///2830/// \param ArgsIn The message arguments.2831ExprResult SemaObjC::BuildInstanceMessage(2832    Expr *Receiver, QualType ReceiverType, SourceLocation SuperLoc,2833    Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc,2834    ArrayRef<SourceLocation> SelectorLocs, SourceLocation RBracLoc,2835    MultiExprArg ArgsIn, bool isImplicit) {2836  assert((Receiver || SuperLoc.isValid()) && "If the Receiver is null, the "2837                                             "SuperLoc must be valid so we can "2838                                             "use it instead.");2839  ASTContext &Context = getASTContext();2840 2841  // The location of the receiver.2842  SourceLocation Loc = SuperLoc.isValid() ? SuperLoc : Receiver->getBeginLoc();2843  SourceRange RecRange =2844      SuperLoc.isValid()? SuperLoc : Receiver->getSourceRange();2845  ArrayRef<SourceLocation> SelectorSlotLocs;2846  if (!SelectorLocs.empty() && SelectorLocs.front().isValid())2847    SelectorSlotLocs = SelectorLocs;2848  else2849    SelectorSlotLocs = Loc;2850  SourceLocation SelLoc = SelectorSlotLocs.front();2851 2852  if (LBracLoc.isInvalid()) {2853    Diag(Loc, diag::err_missing_open_square_message_send)2854      << FixItHint::CreateInsertion(Loc, "[");2855    LBracLoc = Loc;2856  }2857 2858  // If we have a receiver expression, perform appropriate promotions2859  // and determine receiver type.2860  if (Receiver) {2861    if (Receiver->hasPlaceholderType()) {2862      ExprResult Result;2863      if (Receiver->getType() == Context.UnknownAnyTy)2864        Result =2865            SemaRef.forceUnknownAnyToType(Receiver, Context.getObjCIdType());2866      else2867        Result = SemaRef.CheckPlaceholderExpr(Receiver);2868      if (Result.isInvalid()) return ExprError();2869      Receiver = Result.get();2870    }2871 2872    if (Receiver->isTypeDependent()) {2873      // If the receiver is type-dependent, we can't type-check anything2874      // at this point. Build a dependent expression.2875      unsigned NumArgs = ArgsIn.size();2876      Expr **Args = ArgsIn.data();2877      assert(SuperLoc.isInvalid() && "Message to super with dependent type");2878      return ObjCMessageExpr::Create(2879          Context, Context.DependentTy, VK_PRValue, LBracLoc, Receiver, Sel,2880          SelectorLocs, /*Method=*/nullptr, ArrayRef(Args, NumArgs), RBracLoc,2881          isImplicit);2882    }2883 2884    // If necessary, apply function/array conversion to the receiver.2885    // C99 6.7.5.3p[7,8].2886    ExprResult Result = SemaRef.DefaultFunctionArrayLvalueConversion(Receiver);2887    if (Result.isInvalid())2888      return ExprError();2889    Receiver = Result.get();2890    ReceiverType = Receiver->getType();2891 2892    // If the receiver is an ObjC pointer, a block pointer, or an2893    // __attribute__((NSObject)) pointer, we don't need to do any2894    // special conversion in order to look up a receiver.2895    if (ReceiverType->isObjCRetainableType()) {2896      // do nothing2897    } else if (!getLangOpts().ObjCAutoRefCount &&2898               !Context.getObjCIdType().isNull() &&2899               (ReceiverType->isPointerType() ||2900                ReceiverType->isIntegerType())) {2901      // Implicitly convert integers and pointers to 'id' but emit a warning.2902      // But not in ARC.2903      Diag(Loc, diag::warn_bad_receiver_type) << ReceiverType << RecRange;2904      if (ReceiverType->isPointerType()) {2905        Receiver = SemaRef2906                       .ImpCastExprToType(Receiver, Context.getObjCIdType(),2907                                          CK_CPointerToObjCPointerCast)2908                       .get();2909      } else {2910        // TODO: specialized warning on null receivers?2911        bool IsNull = Receiver->isNullPointerConstant(Context,2912                                              Expr::NPC_ValueDependentIsNull);2913        CastKind Kind = IsNull ? CK_NullToPointer : CK_IntegralToPointer;2914        Receiver =2915            SemaRef.ImpCastExprToType(Receiver, Context.getObjCIdType(), Kind)2916                .get();2917      }2918      ReceiverType = Receiver->getType();2919    } else if (getLangOpts().CPlusPlus) {2920      // The receiver must be a complete type.2921      if (SemaRef.RequireCompleteType(Loc, Receiver->getType(),2922                                      diag::err_incomplete_receiver_type))2923        return ExprError();2924 2925      ExprResult result =2926          SemaRef.PerformContextuallyConvertToObjCPointer(Receiver);2927      if (result.isUsable()) {2928        Receiver = result.get();2929        ReceiverType = Receiver->getType();2930      }2931    }2932  }2933 2934  // There's a somewhat weird interaction here where we assume that we2935  // won't actually have a method unless we also don't need to do some2936  // of the more detailed type-checking on the receiver.2937 2938  if (!Method) {2939    // Handle messages to id and __kindof types (where we use the2940    // global method pool).2941    const ObjCObjectType *typeBound = nullptr;2942    bool receiverIsIdLike = ReceiverType->isObjCIdOrObjectKindOfType(Context,2943                                                                     typeBound);2944    if (receiverIsIdLike || ReceiverType->isBlockPointerType() ||2945        (Receiver && Context.isObjCNSObjectType(Receiver->getType()))) {2946      SmallVector<ObjCMethodDecl*, 4> Methods;2947      // If we have a type bound, further filter the methods.2948      CollectMultipleMethodsInGlobalPool(Sel, Methods, true/*InstanceFirst*/,2949                                         true/*CheckTheOther*/, typeBound);2950      if (!Methods.empty()) {2951        // We choose the first method as the initial candidate, then try to2952        // select a better one.2953        Method = Methods[0];2954 2955        if (ObjCMethodDecl *BestMethod = SemaRef.SelectBestMethod(2956                Sel, ArgsIn, Method->isInstanceMethod(), Methods))2957          Method = BestMethod;2958 2959        if (!AreMultipleMethodsInGlobalPool(Sel, Method,2960                                            SourceRange(LBracLoc, RBracLoc),2961                                            receiverIsIdLike, Methods))2962          SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs);2963      }2964    } else if (ReceiverType->isObjCClassOrClassKindOfType() ||2965               ReceiverType->isObjCQualifiedClassType()) {2966      // Handle messages to Class.2967      // We allow sending a message to a qualified Class ("Class<foo>"), which2968      // is ok as long as one of the protocols implements the selector (if not,2969      // warn).2970      if (!ReceiverType->isObjCClassOrClassKindOfType()) {2971        const ObjCObjectPointerType *QClassTy2972          = ReceiverType->getAsObjCQualifiedClassType();2973        // Search protocols for class methods.2974        Method = LookupMethodInQualifiedType(Sel, QClassTy, false);2975        if (!Method) {2976          Method = LookupMethodInQualifiedType(Sel, QClassTy, true);2977          // warn if instance method found for a Class message.2978          if (Method && !isMethodDeclaredInRootProtocol(SemaRef, Method)) {2979            Diag(SelLoc, diag::warn_instance_method_on_class_found)2980              << Method->getSelector() << Sel;2981            Diag(Method->getLocation(), diag::note_method_declared_at)2982              << Method->getDeclName();2983          }2984        }2985      } else {2986        if (ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl()) {2987          if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {2988            // As a guess, try looking for the method in the current interface.2989            // This very well may not produce the "right" method.2990 2991            // First check the public methods in the class interface.2992            Method = ClassDecl->lookupClassMethod(Sel);2993 2994            if (!Method)2995              Method = ClassDecl->lookupPrivateClassMethod(Sel);2996 2997            if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs))2998              return ExprError();2999          }3000        }3001        if (!Method) {3002          // If not messaging 'self', look for any factory method named 'Sel'.3003          if (!Receiver || !isSelfExpr(Receiver)) {3004            // If no class (factory) method was found, check if an _instance_3005            // method of the same name exists in the root class only.3006            SmallVector<ObjCMethodDecl*, 4> Methods;3007            CollectMultipleMethodsInGlobalPool(Sel, Methods,3008                                               false/*InstanceFirst*/,3009                                               true/*CheckTheOther*/);3010            if (!Methods.empty()) {3011              // We choose the first method as the initial candidate, then try3012              // to select a better one.3013              Method = Methods[0];3014 3015              // If we find an instance method, emit warning.3016              if (Method->isInstanceMethod()) {3017                if (const ObjCInterfaceDecl *ID =3018                    dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {3019                  if (ID->getSuperClass())3020                    Diag(SelLoc, diag::warn_root_inst_method_not_found)3021                        << Sel << SourceRange(LBracLoc, RBracLoc);3022                }3023              }3024 3025              if (ObjCMethodDecl *BestMethod = SemaRef.SelectBestMethod(3026                      Sel, ArgsIn, Method->isInstanceMethod(), Methods))3027                Method = BestMethod;3028            }3029          }3030        }3031      }3032    } else {3033      ObjCInterfaceDecl *ClassDecl = nullptr;3034 3035      // We allow sending a message to a qualified ID ("id<foo>"), which is ok as3036      // long as one of the protocols implements the selector (if not, warn).3037      // And as long as message is not deprecated/unavailable (warn if it is).3038      if (const ObjCObjectPointerType *QIdTy3039                                   = ReceiverType->getAsObjCQualifiedIdType()) {3040        // Search protocols for instance methods.3041        Method = LookupMethodInQualifiedType(Sel, QIdTy, true);3042        if (!Method)3043          Method = LookupMethodInQualifiedType(Sel, QIdTy, false);3044        if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs))3045          return ExprError();3046      } else if (const ObjCObjectPointerType *OCIType3047                   = ReceiverType->getAsObjCInterfacePointerType()) {3048        // We allow sending a message to a pointer to an interface (an object).3049        ClassDecl = OCIType->getInterfaceDecl();3050 3051        // Try to complete the type. Under ARC, this is a hard error from which3052        // we don't try to recover.3053        // FIXME: In the non-ARC case, this will still be a hard error if the3054        // definition is found in a module that's not visible.3055        const ObjCInterfaceDecl *forwardClass = nullptr;3056        if (SemaRef.RequireCompleteType(3057                Loc, OCIType->getPointeeType(),3058                getLangOpts().ObjCAutoRefCount3059                    ? diag::err_arc_receiver_forward_instance3060                    : diag::warn_receiver_forward_instance,3061                RecRange)) {3062          if (getLangOpts().ObjCAutoRefCount)3063            return ExprError();3064 3065          forwardClass = OCIType->getInterfaceDecl();3066          Diag(Receiver ? Receiver->getBeginLoc() : SuperLoc,3067               diag::note_receiver_is_id);3068          Method = nullptr;3069        } else {3070          Method = ClassDecl->lookupInstanceMethod(Sel);3071        }3072 3073        if (!Method)3074          // Search protocol qualifiers.3075          Method = LookupMethodInQualifiedType(Sel, OCIType, true);3076 3077        if (!Method) {3078          // If we have implementations in scope, check "private" methods.3079          Method = ClassDecl->lookupPrivateMethod(Sel);3080 3081          if (!Method && getLangOpts().ObjCAutoRefCount) {3082            Diag(SelLoc, diag::err_arc_may_not_respond)3083              << OCIType->getPointeeType() << Sel << RecRange3084              << SourceRange(SelectorLocs.front(), SelectorLocs.back());3085            return ExprError();3086          }3087 3088          if (!Method && (!Receiver || !isSelfExpr(Receiver))) {3089            // If we still haven't found a method, look in the global pool. This3090            // behavior isn't very desirable, however we need it for GCC3091            // compatibility. FIXME: should we deviate??3092            if (OCIType->qual_empty()) {3093              SmallVector<ObjCMethodDecl*, 4> Methods;3094              CollectMultipleMethodsInGlobalPool(Sel, Methods,3095                                                 true/*InstanceFirst*/,3096                                                 false/*CheckTheOther*/);3097              if (!Methods.empty()) {3098                // We choose the first method as the initial candidate, then try3099                // to select a better one.3100                Method = Methods[0];3101 3102                if (ObjCMethodDecl *BestMethod = SemaRef.SelectBestMethod(3103                        Sel, ArgsIn, Method->isInstanceMethod(), Methods))3104                  Method = BestMethod;3105 3106                AreMultipleMethodsInGlobalPool(Sel, Method,3107                                               SourceRange(LBracLoc, RBracLoc),3108                                               true/*receiverIdOrClass*/,3109                                               Methods);3110              }3111              if (Method && !forwardClass)3112                Diag(SelLoc, diag::warn_maynot_respond)3113                  << OCIType->getInterfaceDecl()->getIdentifier()3114                  << Sel << RecRange;3115            }3116          }3117        }3118        if (Method &&3119            SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, forwardClass))3120          return ExprError();3121      } else {3122        // Reject other random receiver types (e.g. structs).3123        Diag(Loc, diag::err_bad_receiver_type) << ReceiverType << RecRange;3124        return ExprError();3125      }3126    }3127  }3128 3129  FunctionScopeInfo *DIFunctionScopeInfo =3130      (Method && Method->getMethodFamily() == OMF_init)3131          ? SemaRef.getEnclosingFunction()3132          : nullptr;3133 3134  if (Method && Method->isDirectMethod()) {3135    if (ReceiverType->isObjCIdType() && !isImplicit) {3136      Diag(Receiver->getExprLoc(),3137           diag::err_messaging_unqualified_id_with_direct_method);3138      Diag(Method->getLocation(), diag::note_direct_method_declared_at)3139          << Method->getDeclName();3140    }3141 3142    // Under ARC, self can't be assigned, and doing a direct call to `self`3143    // when it's a Class is hence safe.  For other cases, we can't trust `self`3144    // is what we think it is, so we reject it.3145    if (ReceiverType->isObjCClassType() && !isImplicit &&3146        !(Receiver->isObjCSelfExpr() && getLangOpts().ObjCAutoRefCount)) {3147      {3148        auto Builder = Diag(Receiver->getExprLoc(),3149                            diag::err_messaging_class_with_direct_method);3150        if (Receiver->isObjCSelfExpr()) {3151          Builder.AddFixItHint(FixItHint::CreateReplacement(3152              RecRange, Method->getClassInterface()->getName()));3153        }3154      }3155      Diag(Method->getLocation(), diag::note_direct_method_declared_at)3156          << Method->getDeclName();3157    }3158 3159    if (SuperLoc.isValid()) {3160      {3161        auto Builder =3162            Diag(SuperLoc, diag::err_messaging_super_with_direct_method);3163        if (ReceiverType->isObjCClassType()) {3164          Builder.AddFixItHint(FixItHint::CreateReplacement(3165              SuperLoc, Method->getClassInterface()->getName()));3166        } else {3167          Builder.AddFixItHint(FixItHint::CreateReplacement(SuperLoc, "self"));3168        }3169      }3170      Diag(Method->getLocation(), diag::note_direct_method_declared_at)3171          << Method->getDeclName();3172    }3173  } else if (ReceiverType->isObjCIdType() && !isImplicit) {3174    Diag(Receiver->getExprLoc(), diag::warn_messaging_unqualified_id);3175  }3176 3177  if (DIFunctionScopeInfo &&3178      DIFunctionScopeInfo->ObjCIsDesignatedInit &&3179      (SuperLoc.isValid() || isSelfExpr(Receiver))) {3180    bool isDesignatedInitChain = false;3181    if (SuperLoc.isValid()) {3182      if (const ObjCObjectPointerType *3183            OCIType = ReceiverType->getAsObjCInterfacePointerType()) {3184        if (const ObjCInterfaceDecl *ID = OCIType->getInterfaceDecl()) {3185          // Either we know this is a designated initializer or we3186          // conservatively assume it because we don't know for sure.3187          if (!ID->declaresOrInheritsDesignatedInitializers() ||3188              ID->isDesignatedInitializer(Sel)) {3189            isDesignatedInitChain = true;3190            DIFunctionScopeInfo->ObjCWarnForNoDesignatedInitChain = false;3191          }3192        }3193      }3194    }3195    if (!isDesignatedInitChain) {3196      const ObjCMethodDecl *InitMethod = nullptr;3197      auto *CurMD = SemaRef.getCurMethodDecl();3198      assert(CurMD && "Current method declaration should not be null");3199      bool isDesignated =3200          CurMD->isDesignatedInitializerForTheInterface(&InitMethod);3201      assert(isDesignated && InitMethod);3202      (void)isDesignated;3203      Diag(SelLoc, SuperLoc.isValid() ?3204             diag::warn_objc_designated_init_non_designated_init_call :3205             diag::warn_objc_designated_init_non_super_designated_init_call);3206      Diag(InitMethod->getLocation(),3207           diag::note_objc_designated_init_marked_here);3208    }3209  }3210 3211  if (DIFunctionScopeInfo &&3212      DIFunctionScopeInfo->ObjCIsSecondaryInit &&3213      (SuperLoc.isValid() || isSelfExpr(Receiver))) {3214    if (SuperLoc.isValid()) {3215      Diag(SelLoc, diag::warn_objc_secondary_init_super_init_call);3216    } else {3217      DIFunctionScopeInfo->ObjCWarnForNoInitDelegation = false;3218    }3219  }3220 3221  // Check the message arguments.3222  unsigned NumArgs = ArgsIn.size();3223  Expr **Args = ArgsIn.data();3224  QualType ReturnType;3225  ExprValueKind VK = VK_PRValue;3226  bool ClassMessage = (ReceiverType->isObjCClassType() ||3227                       ReceiverType->isObjCQualifiedClassType());3228  if (CheckMessageArgumentTypes(Receiver, ReceiverType,3229                                MultiExprArg(Args, NumArgs), Sel, SelectorLocs,3230                                Method, ClassMessage, SuperLoc.isValid(),3231                                LBracLoc, RBracLoc, RecRange, ReturnType, VK))3232    return ExprError();3233 3234  if (Method && !Method->getReturnType()->isVoidType() &&3235      SemaRef.RequireCompleteType(3236          LBracLoc, Method->getReturnType(),3237          diag::err_illegal_message_expr_incomplete_type))3238    return ExprError();3239 3240  // In ARC, forbid the user from sending messages to3241  // retain/release/autorelease/dealloc/retainCount explicitly.3242  if (getLangOpts().ObjCAutoRefCount) {3243    ObjCMethodFamily family =3244      (Method ? Method->getMethodFamily() : Sel.getMethodFamily());3245    switch (family) {3246    case OMF_init:3247      if (Method)3248        checkInitMethod(Method, ReceiverType);3249      break;3250 3251    case OMF_None:3252    case OMF_alloc:3253    case OMF_copy:3254    case OMF_finalize:3255    case OMF_mutableCopy:3256    case OMF_new:3257    case OMF_self:3258    case OMF_initialize:3259      break;3260 3261    case OMF_dealloc:3262    case OMF_retain:3263    case OMF_release:3264    case OMF_autorelease:3265    case OMF_retainCount:3266      Diag(SelLoc, diag::err_arc_illegal_explicit_message)3267        << Sel << RecRange;3268      break;3269 3270    case OMF_performSelector:3271      if (Method && NumArgs >= 1) {3272        if (const auto *SelExp =3273                dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens())) {3274          Selector ArgSel = SelExp->getSelector();3275          ObjCMethodDecl *SelMethod =3276            LookupInstanceMethodInGlobalPool(ArgSel,3277                                             SelExp->getSourceRange());3278          if (!SelMethod)3279            SelMethod =3280              LookupFactoryMethodInGlobalPool(ArgSel,3281                                              SelExp->getSourceRange());3282          if (SelMethod) {3283            ObjCMethodFamily SelFamily = SelMethod->getMethodFamily();3284            switch (SelFamily) {3285              case OMF_alloc:3286              case OMF_copy:3287              case OMF_mutableCopy:3288              case OMF_new:3289              case OMF_init:3290                // Issue error, unless ns_returns_not_retained.3291                if (!SelMethod->hasAttr<NSReturnsNotRetainedAttr>()) {3292                  // selector names a +1 method3293                  Diag(SelLoc,3294                       diag::err_arc_perform_selector_retains);3295                  Diag(SelMethod->getLocation(), diag::note_method_declared_at)3296                    << SelMethod->getDeclName();3297                }3298                break;3299              default:3300                // +0 call. OK. unless ns_returns_retained.3301                if (SelMethod->hasAttr<NSReturnsRetainedAttr>()) {3302                  // selector names a +1 method3303                  Diag(SelLoc,3304                       diag::err_arc_perform_selector_retains);3305                  Diag(SelMethod->getLocation(), diag::note_method_declared_at)3306                    << SelMethod->getDeclName();3307                }3308                break;3309            }3310          }3311        } else {3312          // error (may leak).3313          Diag(SelLoc, diag::warn_arc_perform_selector_leaks);3314          Diag(Args[0]->getExprLoc(), diag::note_used_here);3315        }3316      }3317      break;3318    }3319  }3320 3321  DiagnoseCStringFormatDirectiveInObjCAPI(SemaRef, Method, Sel, Args, NumArgs);3322 3323  // Construct the appropriate ObjCMessageExpr instance.3324  ObjCMessageExpr *Result;3325  if (SuperLoc.isValid())3326    Result = ObjCMessageExpr::Create(3327        Context, ReturnType, VK, LBracLoc, SuperLoc, /*IsInstanceSuper=*/true,3328        ReceiverType, Sel, SelectorLocs, Method, ArrayRef(Args, NumArgs),3329        RBracLoc, isImplicit);3330  else {3331    Result = ObjCMessageExpr::Create(3332        Context, ReturnType, VK, LBracLoc, Receiver, Sel, SelectorLocs, Method,3333        ArrayRef(Args, NumArgs), RBracLoc, isImplicit);3334    if (!isImplicit)3335      checkCocoaAPI(SemaRef, Result);3336  }3337  if (Method) {3338    bool IsClassObjectCall = ClassMessage;3339    // 'self' message receivers in class methods should be treated as message3340    // sends to the class object in order for the semantic checks to be3341    // performed correctly. Messages to 'super' already count as class messages,3342    // so they don't need to be handled here.3343    if (Receiver && isSelfExpr(Receiver)) {3344      if (const auto *OPT = ReceiverType->getAs<ObjCObjectPointerType>()) {3345        if (OPT->getObjectType()->isObjCClass()) {3346          if (const auto *CurMeth = SemaRef.getCurMethodDecl()) {3347            IsClassObjectCall = true;3348            ReceiverType =3349                Context.getObjCInterfaceType(CurMeth->getClassInterface());3350          }3351        }3352      }3353    }3354    checkFoundationAPI(SemaRef, SelLoc, Method, ArrayRef(Args, NumArgs),3355                       ReceiverType, IsClassObjectCall);3356  }3357 3358  if (getLangOpts().ObjCAutoRefCount) {3359    // In ARC, annotate delegate init calls.3360    if (Result->getMethodFamily() == OMF_init &&3361        (SuperLoc.isValid() || isSelfExpr(Receiver))) {3362      // Only consider init calls *directly* in init implementations,3363      // not within blocks.3364      ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext);3365      if (method && method->getMethodFamily() == OMF_init) {3366        // The implicit assignment to self means we also don't want to3367        // consume the result.3368        Result->setDelegateInitCall(true);3369        return Result;3370      }3371    }3372 3373    // In ARC, check for message sends which are likely to introduce3374    // retain cycles.3375    checkRetainCycles(Result);3376  }3377 3378  if (getLangOpts().ObjCWeak) {3379    if (!isImplicit && Method) {3380      if (const ObjCPropertyDecl *Prop = Method->findPropertyDecl()) {3381        bool IsWeak =3382            Prop->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak;3383        if (!IsWeak && Sel.isUnarySelector())3384          IsWeak = ReturnType.getObjCLifetime() & Qualifiers::OCL_Weak;3385        if (IsWeak && !SemaRef.isUnevaluatedContext() &&3386            !getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak,3387                                        LBracLoc))3388          SemaRef.getCurFunction()->recordUseOfWeak(Result, Prop);3389      }3390    }3391  }3392 3393  CheckObjCCircularContainer(Result);3394 3395  return SemaRef.MaybeBindToTemporary(Result);3396}3397 3398static void RemoveSelectorFromWarningCache(SemaObjC &S, Expr *Arg) {3399  if (ObjCSelectorExpr *OSE =3400      dyn_cast<ObjCSelectorExpr>(Arg->IgnoreParenCasts())) {3401    Selector Sel = OSE->getSelector();3402    SourceLocation Loc = OSE->getAtLoc();3403    auto Pos = S.ReferencedSelectors.find(Sel);3404    if (Pos != S.ReferencedSelectors.end() && Pos->second == Loc)3405      S.ReferencedSelectors.erase(Pos);3406  }3407}3408 3409// ActOnInstanceMessage - used for both unary and keyword messages.3410// ArgExprs is optional - if it is present, the number of expressions3411// is obtained from Sel.getNumArgs().3412ExprResult SemaObjC::ActOnInstanceMessage(Scope *S, Expr *Receiver,3413                                          Selector Sel, SourceLocation LBracLoc,3414                                          ArrayRef<SourceLocation> SelectorLocs,3415                                          SourceLocation RBracLoc,3416                                          MultiExprArg Args) {3417  ASTContext &Context = getASTContext();3418  if (!Receiver)3419    return ExprError();3420 3421  // A ParenListExpr can show up while doing error recovery with invalid code.3422  if (isa<ParenListExpr>(Receiver)) {3423    ExprResult Result =3424        SemaRef.MaybeConvertParenListExprToParenExpr(S, Receiver);3425    if (Result.isInvalid()) return ExprError();3426    Receiver = Result.get();3427  }3428 3429  if (RespondsToSelectorSel.isNull()) {3430    IdentifierInfo *SelectorId = &Context.Idents.get("respondsToSelector");3431    RespondsToSelectorSel = Context.Selectors.getUnarySelector(SelectorId);3432  }3433  if (Sel == RespondsToSelectorSel)3434    RemoveSelectorFromWarningCache(*this, Args[0]);3435 3436  return BuildInstanceMessage(Receiver, Receiver->getType(),3437                              /*SuperLoc=*/SourceLocation(), Sel,3438                              /*Method=*/nullptr, LBracLoc, SelectorLocs,3439                              RBracLoc, Args);3440}3441 3442enum ARCConversionTypeClass {3443  /// int, void, struct A3444  ACTC_none,3445 3446  /// id, void (^)()3447  ACTC_retainable,3448 3449  /// id*, id***, void (^*)(),3450  ACTC_indirectRetainable,3451 3452  /// void* might be a normal C type, or it might a CF type.3453  ACTC_voidPtr,3454 3455  /// struct A*3456  ACTC_coreFoundation3457};3458 3459static bool isAnyRetainable(ARCConversionTypeClass ACTC) {3460  return (ACTC == ACTC_retainable ||3461          ACTC == ACTC_coreFoundation ||3462          ACTC == ACTC_voidPtr);3463}3464 3465static bool isAnyCLike(ARCConversionTypeClass ACTC) {3466  return ACTC == ACTC_none ||3467         ACTC == ACTC_voidPtr ||3468         ACTC == ACTC_coreFoundation;3469}3470 3471static ARCConversionTypeClass classifyTypeForARCConversion(QualType type) {3472  bool isIndirect = false;3473 3474  // Ignore an outermost reference type.3475  if (const ReferenceType *ref = type->getAs<ReferenceType>()) {3476    type = ref->getPointeeType();3477    isIndirect = true;3478  }3479 3480  // Drill through pointers and arrays recursively.3481  while (true) {3482    if (const PointerType *ptr = type->getAs<PointerType>()) {3483      type = ptr->getPointeeType();3484 3485      // The first level of pointer may be the innermost pointer on a CF type.3486      if (!isIndirect) {3487        if (type->isVoidType()) return ACTC_voidPtr;3488        if (type->isRecordType()) return ACTC_coreFoundation;3489      }3490    } else if (const ArrayType *array = type->getAsArrayTypeUnsafe()) {3491      type = QualType(array->getElementType()->getBaseElementTypeUnsafe(), 0);3492    } else {3493      break;3494    }3495    isIndirect = true;3496  }3497 3498  if (isIndirect) {3499    if (type->isObjCARCBridgableType())3500      return ACTC_indirectRetainable;3501    return ACTC_none;3502  }3503 3504  if (type->isObjCARCBridgableType())3505    return ACTC_retainable;3506 3507  return ACTC_none;3508}3509 3510namespace {3511  /// A result from the cast checker.3512  enum ACCResult {3513    /// Cannot be casted.3514    ACC_invalid,3515 3516    /// Can be safely retained or not retained.3517    ACC_bottom,3518 3519    /// Can be casted at +0.3520    ACC_plusZero,3521 3522    /// Can be casted at +1.3523    ACC_plusOne3524  };3525  ACCResult merge(ACCResult left, ACCResult right) {3526    if (left == right) return left;3527    if (left == ACC_bottom) return right;3528    if (right == ACC_bottom) return left;3529    return ACC_invalid;3530  }3531 3532  /// A checker which white-lists certain expressions whose conversion3533  /// to or from retainable type would otherwise be forbidden in ARC.3534  class ARCCastChecker : public StmtVisitor<ARCCastChecker, ACCResult> {3535    typedef StmtVisitor<ARCCastChecker, ACCResult> super;3536 3537    ASTContext &Context;3538    ARCConversionTypeClass SourceClass;3539    ARCConversionTypeClass TargetClass;3540    bool Diagnose;3541 3542    static bool isCFType(QualType type) {3543      // Someday this can use ns_bridged.  For now, it has to do this.3544      return type->isCARCBridgableType();3545    }3546 3547  public:3548    ARCCastChecker(ASTContext &Context, ARCConversionTypeClass source,3549                   ARCConversionTypeClass target, bool diagnose)3550      : Context(Context), SourceClass(source), TargetClass(target),3551        Diagnose(diagnose) {}3552 3553    using super::Visit;3554    ACCResult Visit(Expr *e) {3555      return super::Visit(e->IgnoreParens());3556    }3557 3558    ACCResult VisitStmt(Stmt *s) {3559      return ACC_invalid;3560    }3561 3562    /// Null pointer constants can be casted however you please.3563    ACCResult VisitExpr(Expr *e) {3564      if (e->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull))3565        return ACC_bottom;3566      return ACC_invalid;3567    }3568 3569    /// Objective-C string literals can be safely casted.3570    ACCResult VisitObjCStringLiteral(ObjCStringLiteral *e) {3571      // If we're casting to any retainable type, go ahead.  Global3572      // strings are immune to retains, so this is bottom.3573      if (isAnyRetainable(TargetClass)) return ACC_bottom;3574 3575      return ACC_invalid;3576    }3577 3578    /// Look through certain implicit and explicit casts.3579    ACCResult VisitCastExpr(CastExpr *e) {3580      switch (e->getCastKind()) {3581        case CK_NullToPointer:3582          return ACC_bottom;3583 3584        case CK_NoOp:3585        case CK_LValueToRValue:3586        case CK_BitCast:3587        case CK_CPointerToObjCPointerCast:3588        case CK_BlockPointerToObjCPointerCast:3589        case CK_AnyPointerToBlockPointerCast:3590          return Visit(e->getSubExpr());3591 3592        default:3593          return ACC_invalid;3594      }3595    }3596 3597    /// Look through unary extension.3598    ACCResult VisitUnaryExtension(UnaryOperator *e) {3599      return Visit(e->getSubExpr());3600    }3601 3602    /// Ignore the LHS of a comma operator.3603    ACCResult VisitBinComma(BinaryOperator *e) {3604      return Visit(e->getRHS());3605    }3606 3607    /// Conditional operators are okay if both sides are okay.3608    ACCResult VisitConditionalOperator(ConditionalOperator *e) {3609      ACCResult left = Visit(e->getTrueExpr());3610      if (left == ACC_invalid) return ACC_invalid;3611      return merge(left, Visit(e->getFalseExpr()));3612    }3613 3614    /// Look through pseudo-objects.3615    ACCResult VisitPseudoObjectExpr(PseudoObjectExpr *e) {3616      // If we're getting here, we should always have a result.3617      return Visit(e->getResultExpr());3618    }3619 3620    /// Statement expressions are okay if their result expression is okay.3621    ACCResult VisitStmtExpr(StmtExpr *e) {3622      return Visit(e->getSubStmt()->body_back());3623    }3624 3625    /// Some declaration references are okay.3626    ACCResult VisitDeclRefExpr(DeclRefExpr *e) {3627      VarDecl *var = dyn_cast<VarDecl>(e->getDecl());3628      // References to global constants are okay.3629      if (isAnyRetainable(TargetClass) &&3630          isAnyRetainable(SourceClass) &&3631          var &&3632          !var->hasDefinition(Context) &&3633          var->getType().isConstQualified()) {3634 3635        // In system headers, they can also be assumed to be immune to retains.3636        // These are things like 'kCFStringTransformToLatin'.3637        if (Context.getSourceManager().isInSystemHeader(var->getLocation()))3638          return ACC_bottom;3639 3640        return ACC_plusZero;3641      }3642 3643      // Nothing else.3644      return ACC_invalid;3645    }3646 3647    /// Some calls are okay.3648    ACCResult VisitCallExpr(CallExpr *e) {3649      if (FunctionDecl *fn = e->getDirectCallee())3650        if (ACCResult result = checkCallToFunction(fn))3651          return result;3652 3653      return super::VisitCallExpr(e);3654    }3655 3656    ACCResult checkCallToFunction(FunctionDecl *fn) {3657      // Require a CF*Ref return type.3658      if (!isCFType(fn->getReturnType()))3659        return ACC_invalid;3660 3661      if (!isAnyRetainable(TargetClass))3662        return ACC_invalid;3663 3664      // Honor an explicit 'not retained' attribute.3665      if (fn->hasAttr<CFReturnsNotRetainedAttr>())3666        return ACC_plusZero;3667 3668      // Honor an explicit 'retained' attribute, except that for3669      // now we're not going to permit implicit handling of +1 results,3670      // because it's a bit frightening.3671      if (fn->hasAttr<CFReturnsRetainedAttr>())3672        return Diagnose ? ACC_plusOne3673                        : ACC_invalid; // ACC_plusOne if we start accepting this3674 3675      // Recognize this specific builtin function, which is used by CFSTR.3676      unsigned builtinID = fn->getBuiltinID();3677      if (builtinID == Builtin::BI__builtin___CFStringMakeConstantString)3678        return ACC_bottom;3679 3680      // Otherwise, don't do anything implicit with an unaudited function.3681      if (!fn->hasAttr<CFAuditedTransferAttr>())3682        return ACC_invalid;3683 3684      // Otherwise, it's +0 unless it follows the create convention.3685      if (ento::coreFoundation::followsCreateRule(fn))3686        return Diagnose ? ACC_plusOne3687                        : ACC_invalid; // ACC_plusOne if we start accepting this3688 3689      return ACC_plusZero;3690    }3691 3692    ACCResult VisitObjCMessageExpr(ObjCMessageExpr *e) {3693      return checkCallToMethod(e->getMethodDecl());3694    }3695 3696    ACCResult VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *e) {3697      ObjCMethodDecl *method;3698      if (e->isExplicitProperty())3699        method = e->getExplicitProperty()->getGetterMethodDecl();3700      else3701        method = e->getImplicitPropertyGetter();3702      return checkCallToMethod(method);3703    }3704 3705    ACCResult checkCallToMethod(ObjCMethodDecl *method) {3706      if (!method) return ACC_invalid;3707 3708      // Check for message sends to functions returning CF types.  We3709      // just obey the Cocoa conventions with these, even though the3710      // return type is CF.3711      if (!isAnyRetainable(TargetClass) || !isCFType(method->getReturnType()))3712        return ACC_invalid;3713 3714      // If the method is explicitly marked not-retained, it's +0.3715      if (method->hasAttr<CFReturnsNotRetainedAttr>())3716        return ACC_plusZero;3717 3718      // If the method is explicitly marked as returning retained, or its3719      // selector follows a +1 Cocoa convention, treat it as +1.3720      if (method->hasAttr<CFReturnsRetainedAttr>())3721        return ACC_plusOne;3722 3723      switch (method->getSelector().getMethodFamily()) {3724      case OMF_alloc:3725      case OMF_copy:3726      case OMF_mutableCopy:3727      case OMF_new:3728        return ACC_plusOne;3729 3730      default:3731        // Otherwise, treat it as +0.3732        return ACC_plusZero;3733      }3734    }3735  };3736} // end anonymous namespace3737 3738bool SemaObjC::isKnownName(StringRef name) {3739  ASTContext &Context = getASTContext();3740  if (name.empty())3741    return false;3742  LookupResult R(SemaRef, &Context.Idents.get(name), SourceLocation(),3743                 Sema::LookupOrdinaryName);3744  return SemaRef.LookupName(R, SemaRef.TUScope, false);3745}3746 3747template <typename DiagBuilderT>3748static void addFixitForObjCARCConversion(3749    Sema &S, DiagBuilderT &DiagB, CheckedConversionKind CCK,3750    SourceLocation afterLParen, QualType castType, Expr *castExpr,3751    Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName) {3752  // We handle C-style and implicit casts here.3753  switch (CCK) {3754  case CheckedConversionKind::Implicit:3755  case CheckedConversionKind::ForBuiltinOverloadedOp:3756  case CheckedConversionKind::CStyleCast:3757  case CheckedConversionKind::OtherCast:3758    break;3759  case CheckedConversionKind::FunctionalCast:3760    return;3761  }3762 3763  if (CFBridgeName) {3764    if (CCK == CheckedConversionKind::OtherCast) {3765      if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) {3766        SourceRange range(NCE->getOperatorLoc(),3767                          NCE->getAngleBrackets().getEnd());3768        SmallString<32> BridgeCall;3769 3770        SourceManager &SM = S.getSourceManager();3771        char PrevChar = *SM.getCharacterData(range.getBegin().getLocWithOffset(-1));3772        if (Lexer::isAsciiIdentifierContinueChar(PrevChar, S.getLangOpts()))3773          BridgeCall += ' ';3774 3775        BridgeCall += CFBridgeName;3776        DiagB.AddFixItHint(FixItHint::CreateReplacement(range, BridgeCall));3777      }3778      return;3779    }3780    Expr *castedE = castExpr;3781    if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(castedE))3782      castedE = CCE->getSubExpr();3783    castedE = castedE->IgnoreImpCasts();3784    SourceRange range = castedE->getSourceRange();3785 3786    SmallString<32> BridgeCall;3787 3788    SourceManager &SM = S.getSourceManager();3789    char PrevChar = *SM.getCharacterData(range.getBegin().getLocWithOffset(-1));3790    if (Lexer::isAsciiIdentifierContinueChar(PrevChar, S.getLangOpts()))3791      BridgeCall += ' ';3792 3793    BridgeCall += CFBridgeName;3794 3795    if (isa<ParenExpr>(castedE)) {3796      DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),3797                         BridgeCall));3798    } else {3799      BridgeCall += '(';3800      DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),3801                                                    BridgeCall));3802      DiagB.AddFixItHint(FixItHint::CreateInsertion(3803                                       S.getLocForEndOfToken(range.getEnd()),3804                                       ")"));3805    }3806    return;3807  }3808 3809  if (CCK == CheckedConversionKind::CStyleCast) {3810    DiagB.AddFixItHint(FixItHint::CreateInsertion(afterLParen, bridgeKeyword));3811  } else if (CCK == CheckedConversionKind::OtherCast) {3812    if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) {3813      std::string castCode = "(";3814      castCode += bridgeKeyword;3815      castCode += castType.getAsString();3816      castCode += ")";3817      SourceRange Range(NCE->getOperatorLoc(),3818                        NCE->getAngleBrackets().getEnd());3819      DiagB.AddFixItHint(FixItHint::CreateReplacement(Range, castCode));3820    }3821  } else {3822    std::string castCode = "(";3823    castCode += bridgeKeyword;3824    castCode += castType.getAsString();3825    castCode += ")";3826    Expr *castedE = castExpr->IgnoreImpCasts();3827    SourceRange range = castedE->getSourceRange();3828    if (isa<ParenExpr>(castedE)) {3829      DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),3830                         castCode));3831    } else {3832      castCode += "(";3833      DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),3834                                                    castCode));3835      DiagB.AddFixItHint(FixItHint::CreateInsertion(3836                                       S.getLocForEndOfToken(range.getEnd()),3837                                       ")"));3838    }3839  }3840}3841 3842template <typename T>3843static inline T *getObjCBridgeAttr(const TypedefType *TD) {3844  TypedefNameDecl *TDNDecl = TD->getDecl();3845  QualType QT = TDNDecl->getUnderlyingType();3846  if (QT->isPointerType()) {3847    QT = QT->getPointeeType();3848    if (const RecordType *RT = QT->getAsCanonical<RecordType>()) {3849      for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {3850        if (auto *attr = Redecl->getAttr<T>())3851          return attr;3852      }3853    }3854  }3855  return nullptr;3856}3857 3858static ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttrFromType(QualType T,3859                                                            TypedefNameDecl *&TDNDecl) {3860  while (const auto *TD = T->getAs<TypedefType>()) {3861    TDNDecl = TD->getDecl();3862    if (ObjCBridgeRelatedAttr *ObjCBAttr =3863        getObjCBridgeAttr<ObjCBridgeRelatedAttr>(TD))3864      return ObjCBAttr;3865    T = TDNDecl->getUnderlyingType();3866  }3867  return nullptr;3868}3869 3870static void diagnoseObjCARCConversion(Sema &S, SourceRange castRange,3871                                      QualType castType,3872                                      ARCConversionTypeClass castACTC,3873                                      Expr *castExpr, Expr *realCast,3874                                      ARCConversionTypeClass exprACTC,3875                                      CheckedConversionKind CCK) {3876  SourceLocation loc =3877    (castRange.isValid() ? castRange.getBegin() : castExpr->getExprLoc());3878 3879  if (S.makeUnavailableInSystemHeader(loc,3880                                 UnavailableAttr::IR_ARCForbiddenConversion))3881    return;3882 3883  QualType castExprType = castExpr->getType();3884  // Defer emitting a diagnostic for bridge-related casts; that will be3885  // handled by CheckObjCBridgeRelatedConversions.3886  TypedefNameDecl *TDNDecl = nullptr;3887  if ((castACTC == ACTC_coreFoundation &&  exprACTC == ACTC_retainable &&3888       ObjCBridgeRelatedAttrFromType(castType, TDNDecl)) ||3889      (exprACTC == ACTC_coreFoundation && castACTC == ACTC_retainable &&3890       ObjCBridgeRelatedAttrFromType(castExprType, TDNDecl)))3891    return;3892 3893  unsigned srcKind = 0;3894  switch (exprACTC) {3895  case ACTC_none:3896  case ACTC_coreFoundation:3897  case ACTC_voidPtr:3898    srcKind = (castExprType->isPointerType() ? 1 : 0);3899    break;3900  case ACTC_retainable:3901    srcKind = (castExprType->isBlockPointerType() ? 2 : 3);3902    break;3903  case ACTC_indirectRetainable:3904    srcKind = 4;3905    break;3906  }3907 3908  // Check whether this could be fixed with a bridge cast.3909  SourceLocation afterLParen = S.getLocForEndOfToken(castRange.getBegin());3910  SourceLocation noteLoc = afterLParen.isValid() ? afterLParen : loc;3911 3912  unsigned convKindForDiag = Sema::isCast(CCK) ? 0 : 1;3913 3914  // Bridge from an ARC type to a CF type.3915  if (castACTC == ACTC_retainable && isAnyRetainable(exprACTC)) {3916 3917    S.Diag(loc, diag::err_arc_cast_requires_bridge)3918      << convKindForDiag3919      << 2 // of C pointer type3920      << castExprType3921      << unsigned(castType->isBlockPointerType()) // to ObjC|block type3922      << castType3923      << castRange3924      << castExpr->getSourceRange();3925    bool br = S.ObjC().isKnownName("CFBridgingRelease");3926    ACCResult CreateRule =3927      ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr);3928    assert(CreateRule != ACC_bottom && "This cast should already be accepted.");3929    if (CreateRule != ACC_plusOne)3930    {3931      auto DiagB = (CCK != CheckedConversionKind::OtherCast)3932                       ? S.Diag(noteLoc, diag::note_arc_bridge)3933                       : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);3934 3935      addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,3936                                   castType, castExpr, realCast, "__bridge ",3937                                   nullptr);3938    }3939    if (CreateRule != ACC_plusZero)3940    {3941      auto DiagB = (CCK == CheckedConversionKind::OtherCast && !br)3942                       ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_transfer)3943                             << castExprType3944                       : S.Diag(br ? castExpr->getExprLoc() : noteLoc,3945                                diag::note_arc_bridge_transfer)3946                             << castExprType << br;3947 3948      addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,3949                                   castType, castExpr, realCast, "__bridge_transfer ",3950                                   br ? "CFBridgingRelease" : nullptr);3951    }3952 3953    return;3954  }3955 3956  // Bridge from a CF type to an ARC type.3957  if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC)) {3958    bool br = S.ObjC().isKnownName("CFBridgingRetain");3959    S.Diag(loc, diag::err_arc_cast_requires_bridge)3960      << convKindForDiag3961      << unsigned(castExprType->isBlockPointerType()) // of ObjC|block type3962      << castExprType3963      << 2 // to C pointer type3964      << castType3965      << castRange3966      << castExpr->getSourceRange();3967    ACCResult CreateRule =3968      ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr);3969    assert(CreateRule != ACC_bottom && "This cast should already be accepted.");3970    if (CreateRule != ACC_plusOne)3971    {3972      auto DiagB = (CCK != CheckedConversionKind::OtherCast)3973                       ? S.Diag(noteLoc, diag::note_arc_bridge)3974                       : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);3975      addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,3976                                   castType, castExpr, realCast, "__bridge ",3977                                   nullptr);3978    }3979    if (CreateRule != ACC_plusZero)3980    {3981      auto DiagB = (CCK == CheckedConversionKind::OtherCast && !br)3982                       ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_retained)3983                             << castType3984                       : S.Diag(br ? castExpr->getExprLoc() : noteLoc,3985                                diag::note_arc_bridge_retained)3986                             << castType << br;3987 3988      addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,3989                                   castType, castExpr, realCast, "__bridge_retained ",3990                                   br ? "CFBridgingRetain" : nullptr);3991    }3992 3993    return;3994  }3995 3996  S.Diag(loc, diag::err_arc_mismatched_cast)3997    << !convKindForDiag3998    << srcKind << castExprType << castType3999    << castRange << castExpr->getSourceRange();4000}4001 4002template <typename TB>4003static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr,4004                                  bool &HadTheAttribute, bool warn) {4005  QualType T = castExpr->getType();4006  HadTheAttribute = false;4007  while (const auto *TD = T->getAs<TypedefType>()) {4008    TypedefNameDecl *TDNDecl = TD->getDecl();4009    if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {4010      if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {4011        HadTheAttribute = true;4012        if (Parm->isStr("id"))4013          return true;4014 4015        // Check for an existing type with this name.4016        LookupResult R(S, DeclarationName(Parm), SourceLocation(),4017                       Sema::LookupOrdinaryName);4018        if (S.LookupName(R, S.TUScope)) {4019          NamedDecl *Target = R.getFoundDecl();4020          if (Target && isa<ObjCInterfaceDecl>(Target)) {4021            ObjCInterfaceDecl *ExprClass = cast<ObjCInterfaceDecl>(Target);4022            if (const ObjCObjectPointerType *InterfacePointerType =4023                  castType->getAsObjCInterfacePointerType()) {4024              ObjCInterfaceDecl *CastClass4025                = InterfacePointerType->getObjectType()->getInterface();4026              if ((CastClass == ExprClass) ||4027                  (CastClass && CastClass->isSuperClassOf(ExprClass)))4028                return true;4029              if (warn)4030                S.Diag(castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)4031                    << T << Target->getName() << castType->getPointeeType();4032              return false;4033            } else if (castType->isObjCIdType() ||4034                       (S.Context.ObjCObjectAdoptsQTypeProtocols(4035                          castType, ExprClass)))4036              // ok to cast to 'id'.4037              // casting to id<p-list> is ok if bridge type adopts all of4038              // p-list protocols.4039              return true;4040            else {4041              if (warn) {4042                S.Diag(castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)4043                    << T << Target->getName() << castType;4044                S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);4045                S.Diag(Target->getBeginLoc(), diag::note_declared_at);4046              }4047              return false;4048           }4049          }4050        } else if (!castType->isObjCIdType()) {4051          S.Diag(castExpr->getBeginLoc(),4052                 diag::err_objc_cf_bridged_not_interface)4053              << castExpr->getType() << Parm;4054          S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);4055        }4056        return true;4057      }4058      return false;4059    }4060    T = TDNDecl->getUnderlyingType();4061  }4062  return true;4063}4064 4065template <typename TB>4066static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr,4067                                  bool &HadTheAttribute, bool warn) {4068  QualType T = castType;4069  HadTheAttribute = false;4070  while (const auto *TD = T->getAs<TypedefType>()) {4071    TypedefNameDecl *TDNDecl = TD->getDecl();4072    if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {4073      if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {4074        HadTheAttribute = true;4075        if (Parm->isStr("id"))4076          return true;4077 4078        NamedDecl *Target = nullptr;4079        // Check for an existing type with this name.4080        LookupResult R(S, DeclarationName(Parm), SourceLocation(),4081                       Sema::LookupOrdinaryName);4082        if (S.LookupName(R, S.TUScope)) {4083          Target = R.getFoundDecl();4084          if (Target && isa<ObjCInterfaceDecl>(Target)) {4085            ObjCInterfaceDecl *CastClass = cast<ObjCInterfaceDecl>(Target);4086            if (const ObjCObjectPointerType *InterfacePointerType =4087                  castExpr->getType()->getAsObjCInterfacePointerType()) {4088              ObjCInterfaceDecl *ExprClass4089                = InterfacePointerType->getObjectType()->getInterface();4090              if ((CastClass == ExprClass) ||4091                  (ExprClass && CastClass->isSuperClassOf(ExprClass)))4092                return true;4093              if (warn) {4094                S.Diag(castExpr->getBeginLoc(),4095                       diag::warn_objc_invalid_bridge_to_cf)4096                    << castExpr->getType()->getPointeeType() << T;4097                S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);4098              }4099              return false;4100            } else if (castExpr->getType()->isObjCIdType() ||4101                       (S.Context.QIdProtocolsAdoptObjCObjectProtocols(4102                          castExpr->getType(), CastClass)))4103              // ok to cast an 'id' expression to a CFtype.4104              // ok to cast an 'id<plist>' expression to CFtype provided plist4105              // adopts all of CFtype's ObjetiveC's class plist.4106              return true;4107            else {4108              if (warn) {4109                S.Diag(castExpr->getBeginLoc(),4110                       diag::warn_objc_invalid_bridge_to_cf)4111                    << castExpr->getType() << castType;4112                S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);4113                S.Diag(Target->getBeginLoc(), diag::note_declared_at);4114              }4115              return false;4116            }4117          }4118        }4119        S.Diag(castExpr->getBeginLoc(),4120               diag::err_objc_ns_bridged_invalid_cfobject)4121            << castExpr->getType() << castType;4122        S.Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);4123        if (Target)4124          S.Diag(Target->getBeginLoc(), diag::note_declared_at);4125        return true;4126      }4127      return false;4128    }4129    T = TDNDecl->getUnderlyingType();4130  }4131  return true;4132}4133 4134void SemaObjC::CheckTollFreeBridgeCast(QualType castType, Expr *castExpr) {4135  if (!getLangOpts().ObjC)4136    return;4137  // warn in presence of __bridge casting to or from a toll free bridge cast.4138  ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExpr->getType());4139  ARCConversionTypeClass castACTC = classifyTypeForARCConversion(castType);4140  if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) {4141    bool HasObjCBridgeAttr;4142    bool ObjCBridgeAttrWillNotWarn = CheckObjCBridgeNSCast<ObjCBridgeAttr>(4143        SemaRef, castType, castExpr, HasObjCBridgeAttr, false);4144    if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)4145      return;4146    bool HasObjCBridgeMutableAttr;4147    bool ObjCBridgeMutableAttrWillNotWarn =4148        CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(4149            SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false);4150    if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)4151      return;4152 4153    if (HasObjCBridgeAttr)4154      CheckObjCBridgeNSCast<ObjCBridgeAttr>(SemaRef, castType, castExpr,4155                                            HasObjCBridgeAttr, true);4156    else if (HasObjCBridgeMutableAttr)4157      CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(4158          SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, true);4159  }4160  else if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable) {4161    bool HasObjCBridgeAttr;4162    bool ObjCBridgeAttrWillNotWarn = CheckObjCBridgeCFCast<ObjCBridgeAttr>(4163        SemaRef, castType, castExpr, HasObjCBridgeAttr, false);4164    if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)4165      return;4166    bool HasObjCBridgeMutableAttr;4167    bool ObjCBridgeMutableAttrWillNotWarn =4168        CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(4169            SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false);4170    if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)4171      return;4172 4173    if (HasObjCBridgeAttr)4174      CheckObjCBridgeCFCast<ObjCBridgeAttr>(SemaRef, castType, castExpr,4175                                            HasObjCBridgeAttr, true);4176    else if (HasObjCBridgeMutableAttr)4177      CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(4178          SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, true);4179  }4180}4181 4182void SemaObjC::CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr) {4183  QualType SrcType = castExpr->getType();4184  if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(castExpr)) {4185    if (PRE->isExplicitProperty()) {4186      if (ObjCPropertyDecl *PDecl = PRE->getExplicitProperty())4187        SrcType = PDecl->getType();4188    }4189    else if (PRE->isImplicitProperty()) {4190      if (ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter())4191        SrcType = Getter->getReturnType();4192    }4193  }4194 4195  ARCConversionTypeClass srcExprACTC = classifyTypeForARCConversion(SrcType);4196  ARCConversionTypeClass castExprACTC = classifyTypeForARCConversion(castType);4197  if (srcExprACTC != ACTC_retainable || castExprACTC != ACTC_coreFoundation)4198    return;4199  CheckObjCBridgeRelatedConversions(castExpr->getBeginLoc(), castType, SrcType,4200                                    castExpr);4201}4202 4203bool SemaObjC::CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr,4204                                             CastKind &Kind) {4205  if (!getLangOpts().ObjC)4206    return false;4207  ARCConversionTypeClass exprACTC =4208    classifyTypeForARCConversion(castExpr->getType());4209  ARCConversionTypeClass castACTC = classifyTypeForARCConversion(castType);4210  if ((castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) ||4211      (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable)) {4212    CheckTollFreeBridgeCast(castType, castExpr);4213    Kind = (castACTC == ACTC_coreFoundation) ? CK_BitCast4214                                             : CK_CPointerToObjCPointerCast;4215    return true;4216  }4217  return false;4218}4219 4220bool SemaObjC::checkObjCBridgeRelatedComponents(4221    SourceLocation Loc, QualType DestType, QualType SrcType,4222    ObjCInterfaceDecl *&RelatedClass, ObjCMethodDecl *&ClassMethod,4223    ObjCMethodDecl *&InstanceMethod, TypedefNameDecl *&TDNDecl, bool CfToNs,4224    bool Diagnose) {4225  ASTContext &Context = getASTContext();4226  QualType T = CfToNs ? SrcType : DestType;4227  ObjCBridgeRelatedAttr *ObjCBAttr = ObjCBridgeRelatedAttrFromType(T, TDNDecl);4228  if (!ObjCBAttr)4229    return false;4230 4231  IdentifierInfo *RCId = ObjCBAttr->getRelatedClass();4232  IdentifierInfo *CMId = ObjCBAttr->getClassMethod();4233  IdentifierInfo *IMId = ObjCBAttr->getInstanceMethod();4234  if (!RCId)4235    return false;4236  NamedDecl *Target = nullptr;4237  // Check for an existing type with this name.4238  LookupResult R(SemaRef, DeclarationName(RCId), SourceLocation(),4239                 Sema::LookupOrdinaryName);4240  if (!SemaRef.LookupName(R, SemaRef.TUScope)) {4241    if (Diagnose) {4242      Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId4243            << SrcType << DestType;4244      Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);4245    }4246    return false;4247  }4248  Target = R.getFoundDecl();4249  if (Target && isa<ObjCInterfaceDecl>(Target))4250    RelatedClass = cast<ObjCInterfaceDecl>(Target);4251  else {4252    if (Diagnose) {4253      Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId4254            << SrcType << DestType;4255      Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);4256      if (Target)4257        Diag(Target->getBeginLoc(), diag::note_declared_at);4258    }4259    return false;4260  }4261 4262  // Check for an existing class method with the given selector name.4263  if (CfToNs && CMId) {4264    Selector Sel = Context.Selectors.getUnarySelector(CMId);4265    ClassMethod = RelatedClass->lookupMethod(Sel, false);4266    if (!ClassMethod) {4267      if (Diagnose) {4268        Diag(Loc, diag::err_objc_bridged_related_known_method)4269              << SrcType << DestType << Sel << false;4270        Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);4271      }4272      return false;4273    }4274  }4275 4276  // Check for an existing instance method with the given selector name.4277  if (!CfToNs && IMId) {4278    Selector Sel = Context.Selectors.getNullarySelector(IMId);4279    InstanceMethod = RelatedClass->lookupMethod(Sel, true);4280    if (!InstanceMethod) {4281      if (Diagnose) {4282        Diag(Loc, diag::err_objc_bridged_related_known_method)4283              << SrcType << DestType << Sel << true;4284        Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);4285      }4286      return false;4287    }4288  }4289  return true;4290}4291 4292bool SemaObjC::CheckObjCBridgeRelatedConversions(SourceLocation Loc,4293                                                 QualType DestType,4294                                                 QualType SrcType,4295                                                 Expr *&SrcExpr,4296                                                 bool Diagnose) {4297  ASTContext &Context = getASTContext();4298  ARCConversionTypeClass rhsExprACTC = classifyTypeForARCConversion(SrcType);4299  ARCConversionTypeClass lhsExprACTC = classifyTypeForARCConversion(DestType);4300  bool CfToNs = (rhsExprACTC == ACTC_coreFoundation && lhsExprACTC == ACTC_retainable);4301  bool NsToCf = (rhsExprACTC == ACTC_retainable && lhsExprACTC == ACTC_coreFoundation);4302  if (!CfToNs && !NsToCf)4303    return false;4304 4305  ObjCInterfaceDecl *RelatedClass;4306  ObjCMethodDecl *ClassMethod = nullptr;4307  ObjCMethodDecl *InstanceMethod = nullptr;4308  TypedefNameDecl *TDNDecl = nullptr;4309  if (!checkObjCBridgeRelatedComponents(Loc, DestType, SrcType, RelatedClass,4310                                        ClassMethod, InstanceMethod, TDNDecl,4311                                        CfToNs, Diagnose))4312    return false;4313 4314  if (CfToNs) {4315    // Implicit conversion from CF to ObjC object is needed.4316    if (ClassMethod) {4317      if (Diagnose) {4318        std::string ExpressionString = "[";4319        ExpressionString += RelatedClass->getNameAsString();4320        ExpressionString += " ";4321        ExpressionString += ClassMethod->getSelector().getAsString();4322        SourceLocation SrcExprEndLoc =4323            SemaRef.getLocForEndOfToken(SrcExpr->getEndLoc());4324        // Provide a fixit: [RelatedClass ClassMethod SrcExpr]4325        Diag(Loc, diag::err_objc_bridged_related_known_method)4326            << SrcType << DestType << ClassMethod->getSelector() << false4327            << FixItHint::CreateInsertion(SrcExpr->getBeginLoc(),4328                                          ExpressionString)4329            << FixItHint::CreateInsertion(SrcExprEndLoc, "]");4330        Diag(RelatedClass->getBeginLoc(), diag::note_declared_at);4331        Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);4332 4333        QualType receiverType = Context.getObjCInterfaceType(RelatedClass);4334        // Argument.4335        Expr *args[] = { SrcExpr };4336        ExprResult msg = BuildClassMessageImplicit(receiverType, false,4337                                      ClassMethod->getLocation(),4338                                      ClassMethod->getSelector(), ClassMethod,4339                                      MultiExprArg(args, 1));4340        SrcExpr = msg.get();4341      }4342      return true;4343    }4344  }4345  else {4346    // Implicit conversion from ObjC type to CF object is needed.4347    if (InstanceMethod) {4348      if (Diagnose) {4349        std::string ExpressionString;4350        SourceLocation SrcExprEndLoc =4351            SemaRef.getLocForEndOfToken(SrcExpr->getEndLoc());4352        if (InstanceMethod->isPropertyAccessor())4353          if (const ObjCPropertyDecl *PDecl =4354                  InstanceMethod->findPropertyDecl()) {4355            // fixit: ObjectExpr.propertyname when it is  aproperty accessor.4356            ExpressionString = ".";4357            ExpressionString += PDecl->getNameAsString();4358            Diag(Loc, diag::err_objc_bridged_related_known_method)4359                << SrcType << DestType << InstanceMethod->getSelector() << true4360                << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);4361          }4362        if (ExpressionString.empty()) {4363          // Provide a fixit: [ObjectExpr InstanceMethod]4364          ExpressionString = " ";4365          ExpressionString += InstanceMethod->getSelector().getAsString();4366          ExpressionString += "]";4367 4368          Diag(Loc, diag::err_objc_bridged_related_known_method)4369              << SrcType << DestType << InstanceMethod->getSelector() << true4370              << FixItHint::CreateInsertion(SrcExpr->getBeginLoc(), "[")4371              << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);4372        }4373        Diag(RelatedClass->getBeginLoc(), diag::note_declared_at);4374        Diag(TDNDecl->getBeginLoc(), diag::note_declared_at);4375 4376        ExprResult msg = BuildInstanceMessageImplicit(4377            SrcExpr, SrcType, InstanceMethod->getLocation(),4378            InstanceMethod->getSelector(), InstanceMethod, {});4379        SrcExpr = msg.get();4380      }4381      return true;4382    }4383  }4384  return false;4385}4386 4387SemaObjC::ARCConversionResult4388SemaObjC::CheckObjCConversion(SourceRange castRange, QualType castType,4389                              Expr *&castExpr, CheckedConversionKind CCK,4390                              bool Diagnose, bool DiagnoseCFAudited,4391                              BinaryOperatorKind Opc, bool IsReinterpretCast) {4392  ASTContext &Context = getASTContext();4393  QualType castExprType = castExpr->getType();4394 4395  // For the purposes of the classification, we assume reference types4396  // will bind to temporaries.4397  QualType effCastType = castType;4398  if (const ReferenceType *ref = castType->getAs<ReferenceType>())4399    effCastType = ref->getPointeeType();4400 4401  ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExprType);4402  ARCConversionTypeClass castACTC = classifyTypeForARCConversion(effCastType);4403  if (exprACTC == castACTC) {4404    // Check for viability and report error if casting an rvalue to a4405    // life-time qualifier.4406    if (castACTC == ACTC_retainable &&4407        (CCK == CheckedConversionKind::CStyleCast ||4408         CCK == CheckedConversionKind::OtherCast) &&4409        castType != castExprType) {4410      const Type *DT = castType.getTypePtr();4411      QualType QDT = castType;4412      // We desugar some types but not others. We ignore those4413      // that cannot happen in a cast; i.e. auto, and those which4414      // should not be de-sugared; i.e typedef.4415      if (const ParenType *PT = dyn_cast<ParenType>(DT))4416        QDT = PT->desugar();4417      else if (const TypeOfType *TP = dyn_cast<TypeOfType>(DT))4418        QDT = TP->desugar();4419      else if (const AttributedType *AT = dyn_cast<AttributedType>(DT))4420        QDT = AT->desugar();4421      if (QDT != castType &&4422          QDT.getObjCLifetime() !=  Qualifiers::OCL_None) {4423        if (Diagnose) {4424          SourceLocation loc = (castRange.isValid() ? castRange.getBegin()4425                                                    : castExpr->getExprLoc());4426          Diag(loc, diag::err_arc_nolifetime_behavior);4427        }4428        return ACR_error;4429      }4430    }4431    return ACR_okay;4432  }4433 4434  // The life-time qualifier cast check above is all we need for ObjCWeak.4435  // ObjCAutoRefCount has more restrictions on what is legal.4436  if (!getLangOpts().ObjCAutoRefCount)4437    return ACR_okay;4438 4439  if (isAnyCLike(exprACTC) && isAnyCLike(castACTC)) return ACR_okay;4440 4441  // Allow all of these types to be cast to integer types (but not4442  // vice-versa).4443  if (castACTC == ACTC_none && castType->isIntegralType(Context))4444    return ACR_okay;4445 4446  // Allow casts between pointers to lifetime types (e.g., __strong id*)4447  // and pointers to void (e.g., cv void *). Casting from void* to lifetime*4448  // must be explicit.4449  // Allow conversions between pointers to lifetime types and coreFoundation4450  // pointers too, but only when the conversions are explicit.4451  // Allow conversions requested with a reinterpret_cast that converts an4452  // expression of type T* to type U*.4453  if (exprACTC == ACTC_indirectRetainable &&4454      (castACTC == ACTC_voidPtr ||4455       (castACTC == ACTC_coreFoundation && SemaRef.isCast(CCK)) ||4456       (IsReinterpretCast && effCastType->isAnyPointerType())))4457    return ACR_okay;4458  if (castACTC == ACTC_indirectRetainable &&4459      (((exprACTC == ACTC_voidPtr || exprACTC == ACTC_coreFoundation) &&4460        SemaRef.isCast(CCK)) ||4461       (IsReinterpretCast && castExprType->isAnyPointerType())))4462    return ACR_okay;4463 4464  switch (ARCCastChecker(Context, exprACTC, castACTC, false).Visit(castExpr)) {4465  // For invalid casts, fall through.4466  case ACC_invalid:4467    break;4468 4469  // Do nothing for both bottom and +0.4470  case ACC_bottom:4471  case ACC_plusZero:4472    return ACR_okay;4473 4474  // If the result is +1, consume it here.4475  case ACC_plusOne:4476    castExpr = ImplicitCastExpr::Create(Context, castExpr->getType(),4477                                        CK_ARCConsumeObject, castExpr, nullptr,4478                                        VK_PRValue, FPOptionsOverride());4479    SemaRef.Cleanup.setExprNeedsCleanups(true);4480    return ACR_okay;4481  }4482 4483  // If this is a non-implicit cast from id or block type to a4484  // CoreFoundation type, delay complaining in case the cast is used4485  // in an acceptable context.4486  if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC) &&4487      SemaRef.isCast(CCK))4488    return ACR_unbridged;4489 4490  // Issue a diagnostic about a missing @-sign when implicit casting a cstring4491  // to 'NSString *', instead of falling through to report a "bridge cast"4492  // diagnostic.4493  if (castACTC == ACTC_retainable && exprACTC == ACTC_none &&4494      CheckConversionToObjCLiteral(castType, castExpr, Diagnose))4495    return ACR_error;4496 4497  // Do not issue "bridge cast" diagnostic when implicit casting4498  // a retainable object to a CF type parameter belonging to an audited4499  // CF API function. Let caller issue a normal type mismatched diagnostic4500  // instead.4501  if ((!DiagnoseCFAudited || exprACTC != ACTC_retainable ||4502       castACTC != ACTC_coreFoundation) &&4503      !(exprACTC == ACTC_voidPtr && castACTC == ACTC_retainable &&4504        (Opc == BO_NE || Opc == BO_EQ))) {4505    if (Diagnose)4506      diagnoseObjCARCConversion(SemaRef, castRange, castType, castACTC,4507                                castExpr, castExpr, exprACTC, CCK);4508    return ACR_error;4509  }4510  return ACR_okay;4511}4512 4513/// Given that we saw an expression with the ARCUnbridgedCastTy4514/// placeholder type, complain bitterly.4515void SemaObjC::diagnoseARCUnbridgedCast(Expr *e) {4516  // We expect the spurious ImplicitCastExpr to already have been stripped.4517  assert(!e->hasPlaceholderType(BuiltinType::ARCUnbridgedCast));4518  CastExpr *realCast = cast<CastExpr>(e->IgnoreParens());4519 4520  SourceRange castRange;4521  QualType castType;4522  CheckedConversionKind CCK;4523 4524  if (CStyleCastExpr *cast = dyn_cast<CStyleCastExpr>(realCast)) {4525    castRange = SourceRange(cast->getLParenLoc(), cast->getRParenLoc());4526    castType = cast->getTypeAsWritten();4527    CCK = CheckedConversionKind::CStyleCast;4528  } else if (ExplicitCastExpr *cast = dyn_cast<ExplicitCastExpr>(realCast)) {4529    castRange = cast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange();4530    castType = cast->getTypeAsWritten();4531    CCK = CheckedConversionKind::OtherCast;4532  } else {4533    llvm_unreachable("Unexpected ImplicitCastExpr");4534  }4535 4536  ARCConversionTypeClass castACTC =4537    classifyTypeForARCConversion(castType.getNonReferenceType());4538 4539  Expr *castExpr = realCast->getSubExpr();4540  assert(classifyTypeForARCConversion(castExpr->getType()) == ACTC_retainable);4541 4542  diagnoseObjCARCConversion(SemaRef, castRange, castType, castACTC, castExpr,4543                            realCast, ACTC_retainable, CCK);4544}4545 4546/// stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast4547/// type, remove the placeholder cast.4548Expr *SemaObjC::stripARCUnbridgedCast(Expr *e) {4549  assert(e->hasPlaceholderType(BuiltinType::ARCUnbridgedCast));4550  ASTContext &Context = getASTContext();4551 4552  if (ParenExpr *pe = dyn_cast<ParenExpr>(e)) {4553    Expr *sub = stripARCUnbridgedCast(pe->getSubExpr());4554    return new (Context) ParenExpr(pe->getLParen(), pe->getRParen(), sub);4555  } else if (UnaryOperator *uo = dyn_cast<UnaryOperator>(e)) {4556    assert(uo->getOpcode() == UO_Extension);4557    Expr *sub = stripARCUnbridgedCast(uo->getSubExpr());4558    return UnaryOperator::Create(Context, sub, UO_Extension, sub->getType(),4559                                 sub->getValueKind(), sub->getObjectKind(),4560                                 uo->getOperatorLoc(), false,4561                                 SemaRef.CurFPFeatureOverrides());4562  } else if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {4563    assert(!gse->isResultDependent());4564    assert(!gse->isTypePredicate());4565 4566    unsigned n = gse->getNumAssocs();4567    SmallVector<Expr *, 4> subExprs;4568    SmallVector<TypeSourceInfo *, 4> subTypes;4569    subExprs.reserve(n);4570    subTypes.reserve(n);4571    for (const GenericSelectionExpr::Association assoc : gse->associations()) {4572      subTypes.push_back(assoc.getTypeSourceInfo());4573      Expr *sub = assoc.getAssociationExpr();4574      if (assoc.isSelected())4575        sub = stripARCUnbridgedCast(sub);4576      subExprs.push_back(sub);4577    }4578 4579    return GenericSelectionExpr::Create(4580        Context, gse->getGenericLoc(), gse->getControllingExpr(), subTypes,4581        subExprs, gse->getDefaultLoc(), gse->getRParenLoc(),4582        gse->containsUnexpandedParameterPack(), gse->getResultIndex());4583  } else {4584    assert(isa<ImplicitCastExpr>(e) && "bad form of unbridged cast!");4585    return cast<ImplicitCastExpr>(e)->getSubExpr();4586  }4587}4588 4589bool SemaObjC::CheckObjCARCUnavailableWeakConversion(QualType castType,4590                                                     QualType exprType) {4591  ASTContext &Context = getASTContext();4592  QualType canCastType =4593    Context.getCanonicalType(castType).getUnqualifiedType();4594  QualType canExprType =4595    Context.getCanonicalType(exprType).getUnqualifiedType();4596  if (isa<ObjCObjectPointerType>(canCastType) &&4597      castType.getObjCLifetime() == Qualifiers::OCL_Weak &&4598      canExprType->isObjCObjectPointerType()) {4599    if (const ObjCObjectPointerType *ObjT =4600        canExprType->getAs<ObjCObjectPointerType>())4601      if (const ObjCInterfaceDecl *ObjI = ObjT->getInterfaceDecl())4602        return !ObjI->isArcWeakrefUnavailable();4603  }4604  return true;4605}4606 4607/// Look for an ObjCReclaimReturnedObject cast and destroy it.4608static Expr *maybeUndoReclaimObject(Expr *e) {4609  Expr *curExpr = e, *prevExpr = nullptr;4610 4611  // Walk down the expression until we hit an implicit cast of kind4612  // ARCReclaimReturnedObject or an Expr that is neither a Paren nor a Cast.4613  while (true) {4614    if (auto *pe = dyn_cast<ParenExpr>(curExpr)) {4615      prevExpr = curExpr;4616      curExpr = pe->getSubExpr();4617      continue;4618    }4619 4620    if (auto *ce = dyn_cast<CastExpr>(curExpr)) {4621      if (auto *ice = dyn_cast<ImplicitCastExpr>(ce))4622        if (ice->getCastKind() == CK_ARCReclaimReturnedObject) {4623          if (!prevExpr)4624            return ice->getSubExpr();4625          if (auto *pe = dyn_cast<ParenExpr>(prevExpr))4626            pe->setSubExpr(ice->getSubExpr());4627          else4628            cast<CastExpr>(prevExpr)->setSubExpr(ice->getSubExpr());4629          return e;4630        }4631 4632      prevExpr = curExpr;4633      curExpr = ce->getSubExpr();4634      continue;4635    }4636 4637    // Break out of the loop if curExpr is neither a Paren nor a Cast.4638    break;4639  }4640 4641  return e;4642}4643 4644ExprResult SemaObjC::BuildObjCBridgedCast(SourceLocation LParenLoc,4645                                          ObjCBridgeCastKind Kind,4646                                          SourceLocation BridgeKeywordLoc,4647                                          TypeSourceInfo *TSInfo,4648                                          Expr *SubExpr) {4649  ASTContext &Context = getASTContext();4650  ExprResult SubResult = SemaRef.UsualUnaryConversions(SubExpr);4651  if (SubResult.isInvalid()) return ExprError();4652  SubExpr = SubResult.get();4653 4654  QualType T = TSInfo->getType();4655  QualType FromType = SubExpr->getType();4656 4657  CastKind CK;4658 4659  bool MustConsume = false;4660  if (T->isDependentType() || SubExpr->isTypeDependent()) {4661    // Okay: we'll build a dependent expression type.4662    CK = CK_Dependent;4663  } else if (T->isObjCARCBridgableType() && FromType->isCARCBridgableType()) {4664    // Casting CF -> id4665    CK = (T->isBlockPointerType() ? CK_AnyPointerToBlockPointerCast4666                                  : CK_CPointerToObjCPointerCast);4667    switch (Kind) {4668    case OBC_Bridge:4669      break;4670 4671    case OBC_BridgeRetained: {4672      bool br = isKnownName("CFBridgingRelease");4673      Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)4674        << 24675        << FromType4676        << (T->isBlockPointerType()? 1 : 0)4677        << T4678        << SubExpr->getSourceRange()4679        << Kind;4680      Diag(BridgeKeywordLoc, diag::note_arc_bridge)4681        << FixItHint::CreateReplacement(BridgeKeywordLoc, "__bridge");4682      Diag(BridgeKeywordLoc, diag::note_arc_bridge_transfer)4683        << FromType << br4684        << FixItHint::CreateReplacement(BridgeKeywordLoc,4685                                        br ? "CFBridgingRelease "4686                                           : "__bridge_transfer ");4687 4688      Kind = OBC_Bridge;4689      break;4690    }4691 4692    case OBC_BridgeTransfer:4693      // We must consume the Objective-C object produced by the cast.4694      MustConsume = true;4695      break;4696    }4697  } else if (T->isCARCBridgableType() && FromType->isObjCARCBridgableType()) {4698    // Okay: id -> CF4699    CK = CK_BitCast;4700    switch (Kind) {4701    case OBC_Bridge:4702      // Reclaiming a value that's going to be __bridge-casted to CF4703      // is very dangerous, so we don't do it.4704      SubExpr = maybeUndoReclaimObject(SubExpr);4705      break;4706 4707    case OBC_BridgeRetained:4708      // Produce the object before casting it.4709      SubExpr = ImplicitCastExpr::Create(Context, FromType, CK_ARCProduceObject,4710                                         SubExpr, nullptr, VK_PRValue,4711                                         FPOptionsOverride());4712      break;4713 4714    case OBC_BridgeTransfer: {4715      bool br = isKnownName("CFBridgingRetain");4716      Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)4717        << (FromType->isBlockPointerType()? 1 : 0)4718        << FromType4719        << 24720        << T4721        << SubExpr->getSourceRange()4722        << Kind;4723 4724      Diag(BridgeKeywordLoc, diag::note_arc_bridge)4725        << FixItHint::CreateReplacement(BridgeKeywordLoc, "__bridge ");4726      Diag(BridgeKeywordLoc, diag::note_arc_bridge_retained)4727        << T << br4728        << FixItHint::CreateReplacement(BridgeKeywordLoc,4729                          br ? "CFBridgingRetain " : "__bridge_retained");4730 4731      Kind = OBC_Bridge;4732      break;4733    }4734    }4735  } else {4736    Diag(LParenLoc, diag::err_arc_bridge_cast_incompatible)4737      << FromType << T << Kind4738      << SubExpr->getSourceRange()4739      << TSInfo->getTypeLoc().getSourceRange();4740    return ExprError();4741  }4742 4743  Expr *Result = new (Context) ObjCBridgedCastExpr(LParenLoc, Kind, CK,4744                                                   BridgeKeywordLoc,4745                                                   TSInfo, SubExpr);4746 4747  if (MustConsume) {4748    SemaRef.Cleanup.setExprNeedsCleanups(true);4749    Result = ImplicitCastExpr::Create(Context, T, CK_ARCConsumeObject, Result,4750                                      nullptr, VK_PRValue, FPOptionsOverride());4751  }4752 4753  return Result;4754}4755 4756ExprResult SemaObjC::ActOnObjCBridgedCast(Scope *S, SourceLocation LParenLoc,4757                                          ObjCBridgeCastKind Kind,4758                                          SourceLocation BridgeKeywordLoc,4759                                          ParsedType Type,4760                                          SourceLocation RParenLoc,4761                                          Expr *SubExpr) {4762  ASTContext &Context = getASTContext();4763  TypeSourceInfo *TSInfo = nullptr;4764  QualType T = SemaRef.GetTypeFromParser(Type, &TSInfo);4765  if (Kind == OBC_Bridge)4766    CheckTollFreeBridgeCast(T, SubExpr);4767  if (!TSInfo)4768    TSInfo = Context.getTrivialTypeSourceInfo(T, LParenLoc);4769  return BuildObjCBridgedCast(LParenLoc, Kind, BridgeKeywordLoc, TSInfo,4770                              SubExpr);4771}4772 4773DeclResult SemaObjC::LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S,4774                                            IdentifierInfo *II) {4775  SourceLocation Loc = Lookup.getNameLoc();4776  ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl();4777 4778  // Check for error condition which is already reported.4779  if (!CurMethod)4780    return DeclResult(true);4781 4782  // There are two cases to handle here.  1) scoped lookup could have failed,4783  // in which case we should look for an ivar.  2) scoped lookup could have4784  // found a decl, but that decl is outside the current instance method (i.e.4785  // a global variable).  In these two cases, we do a lookup for an ivar with4786  // this name, if the lookup sucedes, we replace it our current decl.4787 4788  // If we're in a class method, we don't normally want to look for4789  // ivars.  But if we don't find anything else, and there's an4790  // ivar, that's an error.4791  bool IsClassMethod = CurMethod->isClassMethod();4792 4793  bool LookForIvars;4794  if (Lookup.empty())4795    LookForIvars = true;4796  else if (IsClassMethod)4797    LookForIvars = false;4798  else4799    LookForIvars = (Lookup.isSingleResult() &&4800                    Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod());4801  ObjCInterfaceDecl *IFace = nullptr;4802  if (LookForIvars) {4803    IFace = CurMethod->getClassInterface();4804    ObjCInterfaceDecl *ClassDeclared;4805    ObjCIvarDecl *IV = nullptr;4806    if (IFace && (IV = IFace->lookupInstanceVariable(II, ClassDeclared))) {4807      // Diagnose using an ivar in a class method.4808      if (IsClassMethod) {4809        Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName();4810        return DeclResult(true);4811      }4812 4813      // Diagnose the use of an ivar outside of the declaring class.4814      if (IV->getAccessControl() == ObjCIvarDecl::Private &&4815          !declaresSameEntity(ClassDeclared, IFace) &&4816          !getLangOpts().DebuggerSupport)4817        Diag(Loc, diag::err_private_ivar_access) << IV->getDeclName();4818 4819      // Success.4820      return IV;4821    }4822  } else if (CurMethod->isInstanceMethod()) {4823    // We should warn if a local variable hides an ivar.4824    if (ObjCInterfaceDecl *IFace = CurMethod->getClassInterface()) {4825      ObjCInterfaceDecl *ClassDeclared;4826      if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) {4827        if (IV->getAccessControl() != ObjCIvarDecl::Private ||4828            declaresSameEntity(IFace, ClassDeclared))4829          Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName();4830      }4831    }4832  } else if (Lookup.isSingleResult() &&4833             Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod()) {4834    // If accessing a stand-alone ivar in a class method, this is an error.4835    if (const ObjCIvarDecl *IV =4836            dyn_cast<ObjCIvarDecl>(Lookup.getFoundDecl())) {4837      Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName();4838      return DeclResult(true);4839    }4840  }4841 4842  // Didn't encounter an error, didn't find an ivar.4843  return DeclResult(false);4844}4845 4846ExprResult SemaObjC::LookupInObjCMethod(LookupResult &Lookup, Scope *S,4847                                        IdentifierInfo *II,4848                                        bool AllowBuiltinCreation) {4849  // FIXME: Integrate this lookup step into LookupParsedName.4850  DeclResult Ivar = LookupIvarInObjCMethod(Lookup, S, II);4851  if (Ivar.isInvalid())4852    return ExprError();4853  if (Ivar.isUsable())4854    return BuildIvarRefExpr(S, Lookup.getNameLoc(),4855                            cast<ObjCIvarDecl>(Ivar.get()));4856 4857  if (Lookup.empty() && II && AllowBuiltinCreation)4858    SemaRef.LookupBuiltin(Lookup);4859 4860  // Sentinel value saying that we didn't do anything special.4861  return ExprResult(false);4862}4863 4864ExprResult SemaObjC::BuildIvarRefExpr(Scope *S, SourceLocation Loc,4865                                      ObjCIvarDecl *IV) {4866  ASTContext &Context = getASTContext();4867  ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl();4868  assert(CurMethod && CurMethod->isInstanceMethod() &&4869         "should not reference ivar from this context");4870 4871  ObjCInterfaceDecl *IFace = CurMethod->getClassInterface();4872  assert(IFace && "should not reference ivar from this context");4873 4874  // If we're referencing an invalid decl, just return this as a silent4875  // error node.  The error diagnostic was already emitted on the decl.4876  if (IV->isInvalidDecl())4877    return ExprError();4878 4879  // Check if referencing a field with __attribute__((deprecated)).4880  if (SemaRef.DiagnoseUseOfDecl(IV, Loc))4881    return ExprError();4882 4883  // FIXME: This should use a new expr for a direct reference, don't4884  // turn this into Self->ivar, just return a BareIVarExpr or something.4885  IdentifierInfo &II = Context.Idents.get("self");4886  UnqualifiedId SelfName;4887  SelfName.setImplicitSelfParam(&II);4888  CXXScopeSpec SelfScopeSpec;4889  SourceLocation TemplateKWLoc;4890  ExprResult SelfExpr =4891      SemaRef.ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, SelfName,4892                                /*HasTrailingLParen=*/false,4893                                /*IsAddressOfOperand=*/false);4894  if (SelfExpr.isInvalid())4895    return ExprError();4896 4897  SelfExpr = SemaRef.DefaultLvalueConversion(SelfExpr.get());4898  if (SelfExpr.isInvalid())4899    return ExprError();4900 4901  SemaRef.MarkAnyDeclReferenced(Loc, IV, true);4902 4903  ObjCMethodFamily MF = CurMethod->getMethodFamily();4904  if (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize &&4905      !IvarBacksCurrentMethodAccessor(IFace, CurMethod, IV))4906    Diag(Loc, diag::warn_direct_ivar_access) << IV->getDeclName();4907 4908  ObjCIvarRefExpr *Result = new (Context)4909      ObjCIvarRefExpr(IV, IV->getUsageType(SelfExpr.get()->getType()), Loc,4910                      IV->getLocation(), SelfExpr.get(), true, true);4911 4912  if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {4913    if (!SemaRef.isUnevaluatedContext() &&4914        !getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))4915      SemaRef.getCurFunction()->recordUseOfWeak(Result);4916  }4917  if (getLangOpts().ObjCAutoRefCount && !SemaRef.isUnevaluatedContext())4918    if (const BlockDecl *BD = SemaRef.CurContext->getInnermostBlockDecl())4919      SemaRef.ImplicitlyRetainedSelfLocs.push_back({Loc, BD});4920 4921  return Result;4922}4923 4924QualType SemaObjC::FindCompositeObjCPointerType(ExprResult &LHS,4925                                                ExprResult &RHS,4926                                                SourceLocation QuestionLoc) {4927  ASTContext &Context = getASTContext();4928  QualType LHSTy = LHS.get()->getType();4929  QualType RHSTy = RHS.get()->getType();4930 4931  // Handle things like Class and struct objc_class*.  Here we case the result4932  // to the pseudo-builtin, because that will be implicitly cast back to the4933  // redefinition type if an attempt is made to access its fields.4934  if (LHSTy->isObjCClassType() &&4935      (Context.hasSameType(RHSTy, Context.getObjCClassRedefinitionType()))) {4936    RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy,4937                                    CK_CPointerToObjCPointerCast);4938    return LHSTy;4939  }4940  if (RHSTy->isObjCClassType() &&4941      (Context.hasSameType(LHSTy, Context.getObjCClassRedefinitionType()))) {4942    LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy,4943                                    CK_CPointerToObjCPointerCast);4944    return RHSTy;4945  }4946  // And the same for struct objc_object* / id4947  if (LHSTy->isObjCIdType() &&4948      (Context.hasSameType(RHSTy, Context.getObjCIdRedefinitionType()))) {4949    RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy,4950                                    CK_CPointerToObjCPointerCast);4951    return LHSTy;4952  }4953  if (RHSTy->isObjCIdType() &&4954      (Context.hasSameType(LHSTy, Context.getObjCIdRedefinitionType()))) {4955    LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy,4956                                    CK_CPointerToObjCPointerCast);4957    return RHSTy;4958  }4959  // And the same for struct objc_selector* / SEL4960  if (Context.isObjCSelType(LHSTy) &&4961      (Context.hasSameType(RHSTy, Context.getObjCSelRedefinitionType()))) {4962    RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy, CK_BitCast);4963    return LHSTy;4964  }4965  if (Context.isObjCSelType(RHSTy) &&4966      (Context.hasSameType(LHSTy, Context.getObjCSelRedefinitionType()))) {4967    LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy, CK_BitCast);4968    return RHSTy;4969  }4970  // Check constraints for Objective-C object pointers types.4971  if (LHSTy->isObjCObjectPointerType() && RHSTy->isObjCObjectPointerType()) {4972 4973    if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {4974      // Two identical object pointer types are always compatible.4975      return LHSTy;4976    }4977    const ObjCObjectPointerType *LHSOPT =4978        LHSTy->castAs<ObjCObjectPointerType>();4979    const ObjCObjectPointerType *RHSOPT =4980        RHSTy->castAs<ObjCObjectPointerType>();4981    QualType compositeType = LHSTy;4982 4983    // If both operands are interfaces and either operand can be4984    // assigned to the other, use that type as the composite4985    // type. This allows4986    //   xxx ? (A*) a : (B*) b4987    // where B is a subclass of A.4988    //4989    // Additionally, as for assignment, if either type is 'id'4990    // allow silent coercion. Finally, if the types are4991    // incompatible then make sure to use 'id' as the composite4992    // type so the result is acceptable for sending messages to.4993 4994    // FIXME: Consider unifying with 'areComparableObjCPointerTypes'.4995    // It could return the composite type.4996    if (!(compositeType = Context.areCommonBaseCompatible(LHSOPT, RHSOPT))4997             .isNull()) {4998      // Nothing more to do.4999    } else if (Context.canAssignObjCInterfaces(LHSOPT, RHSOPT)) {5000      compositeType = RHSOPT->isObjCBuiltinType() ? RHSTy : LHSTy;5001    } else if (Context.canAssignObjCInterfaces(RHSOPT, LHSOPT)) {5002      compositeType = LHSOPT->isObjCBuiltinType() ? LHSTy : RHSTy;5003    } else if ((LHSOPT->isObjCQualifiedIdType() ||5004                RHSOPT->isObjCQualifiedIdType()) &&5005               Context.ObjCQualifiedIdTypesAreCompatible(LHSOPT, RHSOPT,5006                                                         true)) {5007      // Need to handle "id<xx>" explicitly.5008      // GCC allows qualified id and any Objective-C type to devolve to5009      // id. Currently localizing to here until clear this should be5010      // part of ObjCQualifiedIdTypesAreCompatible.5011      compositeType = Context.getObjCIdType();5012    } else if (LHSTy->isObjCIdType() || RHSTy->isObjCIdType()) {5013      compositeType = Context.getObjCIdType();5014    } else {5015      Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)5016          << LHSTy << RHSTy << LHS.get()->getSourceRange()5017          << RHS.get()->getSourceRange();5018      QualType incompatTy = Context.getObjCIdType();5019      LHS = SemaRef.ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast);5020      RHS = SemaRef.ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast);5021      return incompatTy;5022    }5023    // The object pointer types are compatible.5024    LHS = SemaRef.ImpCastExprToType(LHS.get(), compositeType, CK_BitCast);5025    RHS = SemaRef.ImpCastExprToType(RHS.get(), compositeType, CK_BitCast);5026    return compositeType;5027  }5028  // Check Objective-C object pointer types and 'void *'5029  if (LHSTy->isVoidPointerType() && RHSTy->isObjCObjectPointerType()) {5030    if (getLangOpts().ObjCAutoRefCount) {5031      // ARC forbids the implicit conversion of object pointers to 'void *',5032      // so these types are not compatible.5033      Diag(QuestionLoc, diag::err_cond_voidptr_arc)5034          << LHSTy << RHSTy << LHS.get()->getSourceRange()5035          << RHS.get()->getSourceRange();5036      LHS = RHS = true;5037      return QualType();5038    }5039    QualType lhptee = LHSTy->castAs<PointerType>()->getPointeeType();5040    QualType rhptee = RHSTy->castAs<ObjCObjectPointerType>()->getPointeeType();5041    QualType destPointee =5042        Context.getQualifiedType(lhptee, rhptee.getQualifiers());5043    QualType destType = Context.getPointerType(destPointee);5044    // Add qualifiers if necessary.5045    LHS = SemaRef.ImpCastExprToType(LHS.get(), destType, CK_NoOp);5046    // Promote to void*.5047    RHS = SemaRef.ImpCastExprToType(RHS.get(), destType, CK_BitCast);5048    return destType;5049  }5050  if (LHSTy->isObjCObjectPointerType() && RHSTy->isVoidPointerType()) {5051    if (getLangOpts().ObjCAutoRefCount) {5052      // ARC forbids the implicit conversion of object pointers to 'void *',5053      // so these types are not compatible.5054      Diag(QuestionLoc, diag::err_cond_voidptr_arc)5055          << LHSTy << RHSTy << LHS.get()->getSourceRange()5056          << RHS.get()->getSourceRange();5057      LHS = RHS = true;5058      return QualType();5059    }5060    QualType lhptee = LHSTy->castAs<ObjCObjectPointerType>()->getPointeeType();5061    QualType rhptee = RHSTy->castAs<PointerType>()->getPointeeType();5062    QualType destPointee =5063        Context.getQualifiedType(rhptee, lhptee.getQualifiers());5064    QualType destType = Context.getPointerType(destPointee);5065    // Add qualifiers if necessary.5066    RHS = SemaRef.ImpCastExprToType(RHS.get(), destType, CK_NoOp);5067    // Promote to void*.5068    LHS = SemaRef.ImpCastExprToType(LHS.get(), destType, CK_BitCast);5069    return destType;5070  }5071  return QualType();5072}5073 5074bool SemaObjC::CheckConversionToObjCLiteral(QualType DstType, Expr *&Exp,5075                                            bool Diagnose) {5076  if (!getLangOpts().ObjC)5077    return false;5078 5079  const ObjCObjectPointerType *PT = DstType->getAs<ObjCObjectPointerType>();5080  if (!PT)5081    return false;5082  const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();5083 5084  // Ignore any parens, implicit casts (should only be5085  // array-to-pointer decays), and not-so-opaque values.  The last is5086  // important for making this trigger for property assignments.5087  Expr *SrcExpr = Exp->IgnoreParenImpCasts();5088  if (OpaqueValueExpr *OV = dyn_cast<OpaqueValueExpr>(SrcExpr))5089    if (OV->getSourceExpr())5090      SrcExpr = OV->getSourceExpr()->IgnoreParenImpCasts();5091 5092  if (auto *SL = dyn_cast<StringLiteral>(SrcExpr)) {5093    if (!PT->isObjCIdType() && !(ID && ID->getIdentifier()->isStr("NSString")))5094      return false;5095    if (!SL->isOrdinary())5096      return false;5097 5098    if (Diagnose) {5099      Diag(SL->getBeginLoc(), diag::err_missing_atsign_prefix)5100          << /*string*/ 0 << FixItHint::CreateInsertion(SL->getBeginLoc(), "@");5101      Exp = BuildObjCStringLiteral(SL->getBeginLoc(), SL).get();5102    }5103    return true;5104  }5105 5106  if ((isa<IntegerLiteral>(SrcExpr) || isa<CharacterLiteral>(SrcExpr) ||5107       isa<FloatingLiteral>(SrcExpr) || isa<ObjCBoolLiteralExpr>(SrcExpr) ||5108       isa<CXXBoolLiteralExpr>(SrcExpr)) &&5109      !SrcExpr->isNullPointerConstant(getASTContext(),5110                                      Expr::NPC_NeverValueDependent)) {5111    if (!ID || !ID->getIdentifier()->isStr("NSNumber"))5112      return false;5113    if (Diagnose) {5114      Diag(SrcExpr->getBeginLoc(), diag::err_missing_atsign_prefix)5115          << /*number*/ 15116          << FixItHint::CreateInsertion(SrcExpr->getBeginLoc(), "@");5117      Expr *NumLit =5118          BuildObjCNumericLiteral(SrcExpr->getBeginLoc(), SrcExpr).get();5119      if (NumLit)5120        Exp = NumLit;5121    }5122    return true;5123  }5124 5125  return false;5126}5127 5128/// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals.5129ExprResult SemaObjC::ActOnObjCBoolLiteral(SourceLocation OpLoc,5130                                          tok::TokenKind Kind) {5131  assert((Kind == tok::kw___objc_yes || Kind == tok::kw___objc_no) &&5132         "Unknown Objective-C Boolean value!");5133  ASTContext &Context = getASTContext();5134  QualType BoolT = Context.ObjCBuiltinBoolTy;5135  if (!Context.getBOOLDecl()) {5136    LookupResult Result(SemaRef, &Context.Idents.get("BOOL"), OpLoc,5137                        Sema::LookupOrdinaryName);5138    if (SemaRef.LookupName(Result, SemaRef.getCurScope()) &&5139        Result.isSingleResult()) {5140      NamedDecl *ND = Result.getFoundDecl();5141      if (TypedefDecl *TD = dyn_cast<TypedefDecl>(ND))5142        Context.setBOOLDecl(TD);5143    }5144  }5145  if (Context.getBOOLDecl())5146    BoolT = Context.getBOOLType();5147  return new (Context)5148      ObjCBoolLiteralExpr(Kind == tok::kw___objc_yes, BoolT, OpLoc);5149}5150 5151ExprResult SemaObjC::ActOnObjCAvailabilityCheckExpr(5152    llvm::ArrayRef<AvailabilitySpec> AvailSpecs, SourceLocation AtLoc,5153    SourceLocation RParen) {5154  ASTContext &Context = getASTContext();5155  auto FindSpecVersion =5156      [&](StringRef Platform,5157          const llvm::Triple::OSType &OS) -> std::optional<VersionTuple> {5158    auto Spec = llvm::find_if(AvailSpecs, [&](const AvailabilitySpec &Spec) {5159      return Spec.getPlatform() == Platform;5160    });5161    // Transcribe the "ios" availability check to "maccatalyst" when compiling5162    // for "maccatalyst" if "maccatalyst" is not specified.5163    if (Spec == AvailSpecs.end() && Platform == "maccatalyst") {5164      Spec = llvm::find_if(AvailSpecs, [&](const AvailabilitySpec &Spec) {5165        return Spec.getPlatform() == "ios";5166      });5167    }5168    if (Spec == AvailSpecs.end())5169      return std::nullopt;5170 5171    return llvm::Triple::getCanonicalVersionForOS(5172        OS, Spec->getVersion(),5173        llvm::Triple::isValidVersionForOS(OS, Spec->getVersion()));5174  };5175 5176  VersionTuple Version;5177  if (auto MaybeVersion =5178          FindSpecVersion(Context.getTargetInfo().getPlatformName(),5179                          Context.getTargetInfo().getTriple().getOS()))5180    Version = *MaybeVersion;5181 5182  // The use of `@available` in the enclosing context should be analyzed to5183  // warn when it's used inappropriately (i.e. not if(@available)).5184  if (FunctionScopeInfo *Context = SemaRef.getCurFunctionAvailabilityContext())5185    Context->HasPotentialAvailabilityViolations = true;5186 5187  return new (Context)5188      ObjCAvailabilityCheckExpr(Version, AtLoc, RParen, Context.BoolTy);5189}5190 5191/// Prepare a conversion of the given expression to an ObjC object5192/// pointer type.5193CastKind SemaObjC::PrepareCastToObjCObjectPointer(ExprResult &E) {5194  QualType type = E.get()->getType();5195  if (type->isObjCObjectPointerType()) {5196    return CK_BitCast;5197  } else if (type->isBlockPointerType()) {5198    SemaRef.maybeExtendBlockObject(E);5199    return CK_BlockPointerToObjCPointerCast;5200  } else {5201    assert(type->isPointerType());5202    return CK_CPointerToObjCPointerCast;5203  }5204}5205 5206SemaObjC::ObjCLiteralKind SemaObjC::CheckLiteralKind(Expr *FromE) {5207  FromE = FromE->IgnoreParenImpCasts();5208  switch (FromE->getStmtClass()) {5209  default:5210    break;5211  case Stmt::ObjCStringLiteralClass:5212    // "string literal"5213    return LK_String;5214  case Stmt::ObjCArrayLiteralClass:5215    // "array literal"5216    return LK_Array;5217  case Stmt::ObjCDictionaryLiteralClass:5218    // "dictionary literal"5219    return LK_Dictionary;5220  case Stmt::BlockExprClass:5221    return LK_Block;5222  case Stmt::ObjCBoxedExprClass: {5223    Expr *Inner = cast<ObjCBoxedExpr>(FromE)->getSubExpr()->IgnoreParens();5224    switch (Inner->getStmtClass()) {5225    case Stmt::IntegerLiteralClass:5226    case Stmt::FloatingLiteralClass:5227    case Stmt::CharacterLiteralClass:5228    case Stmt::ObjCBoolLiteralExprClass:5229    case Stmt::CXXBoolLiteralExprClass:5230      // "numeric literal"5231      return LK_Numeric;5232    case Stmt::ImplicitCastExprClass: {5233      CastKind CK = cast<CastExpr>(Inner)->getCastKind();5234      // Boolean literals can be represented by implicit casts.5235      if (CK == CK_IntegralToBoolean || CK == CK_IntegralCast)5236        return LK_Numeric;5237      break;5238    }5239    default:5240      break;5241    }5242    return LK_Boxed;5243  }5244  }5245  return LK_None;5246}5247