llvm/clang/lib/Sema/SemaExprObjC.cpp

//===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file implements semantic analysis for Objective-C expressions.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTContext.h"
#include "clang/AST/Availability.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Edit/Commit.h"
#include "clang/Edit/Rewriters.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaObjC.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ConvertUTF.h"
#include <optional>

usingnamespaceclang;
usingnamespacesema;
ArrayRef;

ExprResult SemaObjC::ParseObjCStringLiteral(SourceLocation *AtLocs,
                                            ArrayRef<Expr *> Strings) {}

ExprResult SemaObjC::BuildObjCStringLiteral(SourceLocation AtLoc,
                                            StringLiteral *S) {}

/// Emits an error if the given method does not exist, or if the return
/// type is not an Objective-C object.
static bool validateBoxingMethod(Sema &S, SourceLocation Loc,
                                 const ObjCInterfaceDecl *Class,
                                 Selector Sel, const ObjCMethodDecl *Method) {}

/// Maps ObjCLiteralKind to NSClassIdKindKind
static NSAPI::NSClassIdKindKind
ClassKindFromLiteralKind(SemaObjC::ObjCLiteralKind LiteralKind) {}

/// Validates ObjCInterfaceDecl availability.
/// ObjCInterfaceDecl, used to create ObjC literals, should be defined
/// if clang not in a debugger mode.
static bool
ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl,
                                 SourceLocation Loc,
                                 SemaObjC::ObjCLiteralKind LiteralKind) {}

/// Looks up ObjCInterfaceDecl of a given NSClassIdKindKind.
/// Used to create ObjC literals, such as NSDictionary (@{}),
/// NSArray (@[]) and Boxed Expressions (@())
static ObjCInterfaceDecl *
LookupObjCInterfaceDeclForLiteral(Sema &S, SourceLocation Loc,
                                  SemaObjC::ObjCLiteralKind LiteralKind) {}

/// Retrieve the NSNumber factory method that should be used to create
/// an Objective-C literal for the given type.
static ObjCMethodDecl *getNSNumberFactoryMethod(SemaObjC &S, SourceLocation Loc,
                                                QualType NumberType,
                                                bool isLiteral = false,
                                                SourceRange R = SourceRange()) {}

/// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the
/// numeric literal expression. Type of the expression will be "NSNumber *".
ExprResult SemaObjC::BuildObjCNumericLiteral(SourceLocation AtLoc,
                                             Expr *Number) {}

ExprResult SemaObjC::ActOnObjCBoolLiteral(SourceLocation AtLoc,
                                          SourceLocation ValueLoc, bool Value) {}

/// Check that the given expression is a valid element of an Objective-C
/// collection literal.
static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element,
                                                    QualType T,
                                                    bool ArrayLiteral = false) {}

ExprResult SemaObjC::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {}

/// Build an ObjC subscript pseudo-object expression, given that
/// that's supported by the runtime.
ExprResult SemaObjC::BuildObjCSubscriptExpression(
    SourceLocation RB, Expr *BaseExpr, Expr *IndexExpr,
    ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod) {}

ExprResult SemaObjC::BuildObjCArrayLiteral(SourceRange SR,
                                           MultiExprArg Elements) {}

/// Check for duplicate keys in an ObjC dictionary literal. For instance:
///   NSDictionary *nd = @{ @"foo" : @"bar", @"foo" : @"baz" };
static void
CheckObjCDictionaryLiteralDuplicateKeys(Sema &S,
                                        ObjCDictionaryLiteral *Literal) {}

ExprResult SemaObjC::BuildObjCDictionaryLiteral(
    SourceRange SR, MutableArrayRef<ObjCDictionaryElement> Elements) {}

ExprResult SemaObjC::BuildObjCEncodeExpression(SourceLocation AtLoc,
                                               TypeSourceInfo *EncodedTypeInfo,
                                               SourceLocation RParenLoc) {}

ExprResult SemaObjC::ParseObjCEncodeExpression(SourceLocation AtLoc,
                                               SourceLocation EncodeLoc,
                                               SourceLocation LParenLoc,
                                               ParsedType ty,
                                               SourceLocation RParenLoc) {}

static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S,
                                               SourceLocation AtLoc,
                                               SourceLocation LParenLoc,
                                               SourceLocation RParenLoc,
                                               ObjCMethodDecl *Method,
                                               ObjCMethodList &MethList) {}

static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc,
                                        ObjCMethodDecl *Method,
                                        SourceLocation LParenLoc,
                                        SourceLocation RParenLoc,
                                        bool WarnMultipleSelectors) {}

static ObjCMethodDecl *LookupDirectMethodInMethodList(Sema &S, Selector Sel,
                                                      ObjCMethodList &MethList,
                                                      bool &onlyDirect,
                                                      bool &anyDirect) {}

// Search the global pool for (potentially) direct methods matching the given
// selector. If a non-direct method is found, set \param onlyDirect to false. If
// a direct method is found, set \param anyDirect to true. Returns a direct
// method, if any.
static ObjCMethodDecl *LookupDirectMethodInGlobalPool(Sema &S, Selector Sel,
                                                      bool &onlyDirect,
                                                      bool &anyDirect) {}

static ObjCMethodDecl *findMethodInCurrentClass(Sema &S, Selector Sel) {}

ExprResult SemaObjC::ParseObjCSelectorExpression(Selector Sel,
                                                 SourceLocation AtLoc,
                                                 SourceLocation SelLoc,
                                                 SourceLocation LParenLoc,
                                                 SourceLocation RParenLoc,
                                                 bool WarnMultipleSelectors) {}

ExprResult SemaObjC::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
                                                 SourceLocation AtLoc,
                                                 SourceLocation ProtoLoc,
                                                 SourceLocation LParenLoc,
                                                 SourceLocation ProtoIdLoc,
                                                 SourceLocation RParenLoc) {}

/// Try to capture an implicit reference to 'self'.
ObjCMethodDecl *SemaObjC::tryCaptureObjCSelf(SourceLocation Loc) {}

static QualType stripObjCInstanceType(ASTContext &Context, QualType T) {}

/// Determine the result type of a message send based on the receiver type,
/// method, and the kind of message send.
///
/// This is the "base" result type, which will still need to be adjusted
/// to account for nullability.
static QualType getBaseMessageSendResultType(Sema &S,
                                             QualType ReceiverType,
                                             ObjCMethodDecl *Method,
                                             bool isClassMessage,
                                             bool isSuperMessage) {}

QualType SemaObjC::getMessageSendResultType(const Expr *Receiver,
                                            QualType ReceiverType,
                                            ObjCMethodDecl *Method,
                                            bool isClassMessage,
                                            bool isSuperMessage) {}

/// Look for an ObjC method whose result type exactly matches the given type.
static const ObjCMethodDecl *
findExplicitInstancetypeDeclarer(const ObjCMethodDecl *MD,
                                 QualType instancetype) {}

void SemaObjC::EmitRelatedResultTypeNoteForReturn(QualType destType) {}

void SemaObjC::EmitRelatedResultTypeNote(const Expr *E) {}

bool SemaObjC::CheckMessageArgumentTypes(
    const Expr *Receiver, QualType ReceiverType, MultiExprArg Args,
    Selector Sel, ArrayRef<SourceLocation> SelectorLocs, ObjCMethodDecl *Method,
    bool isClassMessage, bool isSuperMessage, SourceLocation lbrac,
    SourceLocation rbrac, SourceRange RecRange, QualType &ReturnType,
    ExprValueKind &VK) {}

bool SemaObjC::isSelfExpr(Expr *RExpr) {}

bool SemaObjC::isSelfExpr(Expr *receiver, const ObjCMethodDecl *method) {}

/// LookupMethodInType - Look up a method in an ObjCObjectType.
ObjCMethodDecl *SemaObjC::LookupMethodInObjectType(Selector sel, QualType type,
                                                   bool isInstance) {}

/// LookupMethodInQualifiedType - Lookups up a method in protocol qualifier
/// list of a qualified objective pointer type.
ObjCMethodDecl *SemaObjC::LookupMethodInQualifiedType(
    Selector Sel, const ObjCObjectPointerType *OPT, bool Instance) {}

/// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an
/// objective C interface.  This is a property reference expression.
ExprResult SemaObjC::HandleExprPropertyRefExpr(
    const ObjCObjectPointerType *OPT, Expr *BaseExpr, SourceLocation OpLoc,
    DeclarationName MemberName, SourceLocation MemberLoc,
    SourceLocation SuperLoc, QualType SuperType, bool Super) {}

ExprResult SemaObjC::ActOnClassPropertyRefExpr(
    const IdentifierInfo &receiverName, const IdentifierInfo &propertyName,
    SourceLocation receiverNameLoc, SourceLocation propertyNameLoc) {}

namespace {

class ObjCInterfaceOrSuperCCC final : public CorrectionCandidateCallback {};

} // end anonymous namespace

SemaObjC::ObjCMessageKind
SemaObjC::getObjCMessageKind(Scope *S, IdentifierInfo *Name,
                             SourceLocation NameLoc, bool IsSuper,
                             bool HasTrailingDot, ParsedType &ReceiverType) {}

ExprResult SemaObjC::ActOnSuperMessage(Scope *S, SourceLocation SuperLoc,
                                       Selector Sel, SourceLocation LBracLoc,
                                       ArrayRef<SourceLocation> SelectorLocs,
                                       SourceLocation RBracLoc,
                                       MultiExprArg Args) {}

ExprResult SemaObjC::BuildClassMessageImplicit(QualType ReceiverType,
                                               bool isSuperReceiver,
                                               SourceLocation Loc, Selector Sel,
                                               ObjCMethodDecl *Method,
                                               MultiExprArg Args) {}

static void applyCocoaAPICheck(Sema &S, const ObjCMessageExpr *Msg,
                               unsigned DiagID,
                               bool (*refactor)(const ObjCMessageExpr *,
                                              const NSAPI &, edit::Commit &)) {}

static void checkCocoaAPI(Sema &S, const ObjCMessageExpr *Msg) {}

static void checkFoundationAPI(Sema &S, SourceLocation Loc,
                               const ObjCMethodDecl *Method,
                               ArrayRef<Expr *> Args, QualType ReceiverType,
                               bool IsClassObjectCall) {}

/// Diagnose use of %s directive in an NSString which is being passed
/// as formatting string to formatting method.
static void
DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S,
                                        ObjCMethodDecl *Method,
                                        Selector Sel,
                                        Expr **Args, unsigned NumArgs) {}

/// Build an Objective-C class message expression.
///
/// This routine takes care of both normal class messages and
/// class messages to the superclass.
///
/// \param ReceiverTypeInfo Type source information that describes the
/// receiver of this message. This may be NULL, in which case we are
/// sending to the superclass and \p SuperLoc must be a valid source
/// location.

/// \param ReceiverType The type of the object receiving the
/// message. When \p ReceiverTypeInfo is non-NULL, this is the same
/// type as that refers to. For a superclass send, this is the type of
/// the superclass.
///
/// \param SuperLoc The location of the "super" keyword in a
/// superclass message.
///
/// \param Sel The selector to which the message is being sent.
///
/// \param Method The method that this class message is invoking, if
/// already known.
///
/// \param LBracLoc The location of the opening square bracket ']'.
///
/// \param RBracLoc The location of the closing square bracket ']'.
///
/// \param ArgsIn The message arguments.
ExprResult SemaObjC::BuildClassMessage(
    TypeSourceInfo *ReceiverTypeInfo, QualType ReceiverType,
    SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method,
    SourceLocation LBracLoc, ArrayRef<SourceLocation> SelectorLocs,
    SourceLocation RBracLoc, MultiExprArg ArgsIn, bool isImplicit) {}

// ActOnClassMessage - used for both unary and keyword messages.
// ArgExprs is optional - if it is present, the number of expressions
// is obtained from Sel.getNumArgs().
ExprResult SemaObjC::ActOnClassMessage(Scope *S, ParsedType Receiver,
                                       Selector Sel, SourceLocation LBracLoc,
                                       ArrayRef<SourceLocation> SelectorLocs,
                                       SourceLocation RBracLoc,
                                       MultiExprArg Args) {}

ExprResult SemaObjC::BuildInstanceMessageImplicit(
    Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel,
    ObjCMethodDecl *Method, MultiExprArg Args) {}

static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M) {}

/// Build an Objective-C instance message expression.
///
/// This routine takes care of both normal instance messages and
/// instance messages to the superclass instance.
///
/// \param Receiver The expression that computes the object that will
/// receive this message. This may be empty, in which case we are
/// sending to the superclass instance and \p SuperLoc must be a valid
/// source location.
///
/// \param ReceiverType The (static) type of the object receiving the
/// message. When a \p Receiver expression is provided, this is the
/// same type as that expression. For a superclass instance send, this
/// is a pointer to the type of the superclass.
///
/// \param SuperLoc The location of the "super" keyword in a
/// superclass instance message.
///
/// \param Sel The selector to which the message is being sent.
///
/// \param Method The method that this instance message is invoking, if
/// already known.
///
/// \param LBracLoc The location of the opening square bracket ']'.
///
/// \param RBracLoc The location of the closing square bracket ']'.
///
/// \param ArgsIn The message arguments.
ExprResult SemaObjC::BuildInstanceMessage(
    Expr *Receiver, QualType ReceiverType, SourceLocation SuperLoc,
    Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc,
    ArrayRef<SourceLocation> SelectorLocs, SourceLocation RBracLoc,
    MultiExprArg ArgsIn, bool isImplicit) {}

static void RemoveSelectorFromWarningCache(SemaObjC &S, Expr *Arg) {}

// ActOnInstanceMessage - used for both unary and keyword messages.
// ArgExprs is optional - if it is present, the number of expressions
// is obtained from Sel.getNumArgs().
ExprResult SemaObjC::ActOnInstanceMessage(Scope *S, Expr *Receiver,
                                          Selector Sel, SourceLocation LBracLoc,
                                          ArrayRef<SourceLocation> SelectorLocs,
                                          SourceLocation RBracLoc,
                                          MultiExprArg Args) {}

enum ARCConversionTypeClass {};

static bool isAnyRetainable(ARCConversionTypeClass ACTC) {}

static bool isAnyCLike(ARCConversionTypeClass ACTC) {}

static ARCConversionTypeClass classifyTypeForARCConversion(QualType type) {}

namespace {
  /// A result from the cast checker.
  enum ACCResult {};
  ACCResult merge(ACCResult left, ACCResult right) {}

  /// A checker which white-lists certain expressions whose conversion
  /// to or from retainable type would otherwise be forbidden in ARC.
  class ARCCastChecker : public StmtVisitor<ARCCastChecker, ACCResult> {};
} // end anonymous namespace

bool SemaObjC::isKnownName(StringRef name) {}

template <typename DiagBuilderT>
static void addFixitForObjCARCConversion(
    Sema &S, DiagBuilderT &DiagB, CheckedConversionKind CCK,
    SourceLocation afterLParen, QualType castType, Expr *castExpr,
    Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName) {}

template <typename T>
static inline T *getObjCBridgeAttr(const TypedefType *TD) {}

static ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttrFromType(QualType T,
                                                            TypedefNameDecl *&TDNDecl) {}

static void diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
                                      QualType castType,
                                      ARCConversionTypeClass castACTC,
                                      Expr *castExpr, Expr *realCast,
                                      ARCConversionTypeClass exprACTC,
                                      CheckedConversionKind CCK) {}

template <typename TB>
static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr,
                                  bool &HadTheAttribute, bool warn) {}

template <typename TB>
static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr,
                                  bool &HadTheAttribute, bool warn) {}

void SemaObjC::CheckTollFreeBridgeCast(QualType castType, Expr *castExpr) {}

void SemaObjC::CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr) {}

bool SemaObjC::CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr,
                                             CastKind &Kind) {}

bool SemaObjC::checkObjCBridgeRelatedComponents(
    SourceLocation Loc, QualType DestType, QualType SrcType,
    ObjCInterfaceDecl *&RelatedClass, ObjCMethodDecl *&ClassMethod,
    ObjCMethodDecl *&InstanceMethod, TypedefNameDecl *&TDNDecl, bool CfToNs,
    bool Diagnose) {}

bool SemaObjC::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
                                                 QualType DestType,
                                                 QualType SrcType,
                                                 Expr *&SrcExpr,
                                                 bool Diagnose) {}

SemaObjC::ARCConversionResult
SemaObjC::CheckObjCConversion(SourceRange castRange, QualType castType,
                              Expr *&castExpr, CheckedConversionKind CCK,
                              bool Diagnose, bool DiagnoseCFAudited,
                              BinaryOperatorKind Opc) {}

/// Given that we saw an expression with the ARCUnbridgedCastTy
/// placeholder type, complain bitterly.
void SemaObjC::diagnoseARCUnbridgedCast(Expr *e) {}

/// stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast
/// type, remove the placeholder cast.
Expr *SemaObjC::stripARCUnbridgedCast(Expr *e) {}

bool SemaObjC::CheckObjCARCUnavailableWeakConversion(QualType castType,
                                                     QualType exprType) {}

/// Look for an ObjCReclaimReturnedObject cast and destroy it.
static Expr *maybeUndoReclaimObject(Expr *e) {}

ExprResult SemaObjC::BuildObjCBridgedCast(SourceLocation LParenLoc,
                                          ObjCBridgeCastKind Kind,
                                          SourceLocation BridgeKeywordLoc,
                                          TypeSourceInfo *TSInfo,
                                          Expr *SubExpr) {}

ExprResult SemaObjC::ActOnObjCBridgedCast(Scope *S, SourceLocation LParenLoc,
                                          ObjCBridgeCastKind Kind,
                                          SourceLocation BridgeKeywordLoc,
                                          ParsedType Type,
                                          SourceLocation RParenLoc,
                                          Expr *SubExpr) {}

DeclResult SemaObjC::LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S,
                                            IdentifierInfo *II) {}

ExprResult SemaObjC::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
                                        IdentifierInfo *II,
                                        bool AllowBuiltinCreation) {}

ExprResult SemaObjC::BuildIvarRefExpr(Scope *S, SourceLocation Loc,
                                      ObjCIvarDecl *IV) {}

QualType SemaObjC::FindCompositeObjCPointerType(ExprResult &LHS,
                                                ExprResult &RHS,
                                                SourceLocation QuestionLoc) {}

bool SemaObjC::CheckConversionToObjCLiteral(QualType DstType, Expr *&Exp,
                                            bool Diagnose) {}

/// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals.
ExprResult SemaObjC::ActOnObjCBoolLiteral(SourceLocation OpLoc,
                                          tok::TokenKind Kind) {}

ExprResult SemaObjC::ActOnObjCAvailabilityCheckExpr(
    llvm::ArrayRef<AvailabilitySpec> AvailSpecs, SourceLocation AtLoc,
    SourceLocation RParen) {}

/// Prepare a conversion of the given expression to an ObjC object
/// pointer type.
CastKind SemaObjC::PrepareCastToObjCObjectPointer(ExprResult &E) {}

SemaObjC::ObjCLiteralKind SemaObjC::CheckLiteralKind(Expr *FromE) {}