//===- ExprObjC.cpp - (ObjC) Expression AST Node Implementation -----------===//
//
// 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 the subclesses of Expr class declared in ExprObjC.h
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ExprObjC.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/SelectorLocationsKind.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <cassert>
#include <cstdint>

using namespace clang;

ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,
                                   ObjCMethodDecl *Method, SourceRange SR)
    : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
           false, false),
      NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {
  Expr **SaveElements = getElements();
  for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
    if (Elements[I]->isTypeDependent() || Elements[I]->isValueDependent())
      ExprBits.ValueDependent = true;
    if (Elements[I]->isInstantiationDependent())
      ExprBits.InstantiationDependent = true;
    if (Elements[I]->containsUnexpandedParameterPack())
      ExprBits.ContainsUnexpandedParameterPack = true;

    SaveElements[I] = Elements[I];
  }
}

ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
                                           ArrayRef<Expr *> Elements,
                                           QualType T, ObjCMethodDecl *Method,
                                           SourceRange SR) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
  return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
}

ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
                                                unsigned NumElements) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
  return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
}

ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
                                             bool HasPackExpansions, QualType T,
                                             ObjCMethodDecl *method,
                                             SourceRange SR)
    : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
           false, false),
      NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
      DictWithObjectsMethod(method) {
  KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();
  ExpansionData *Expansions =
      HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr;
  for (unsigned I = 0; I < NumElements; I++) {
    if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() ||
        VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent())
      ExprBits.ValueDependent = true;
    if (VK[I].Key->isInstantiationDependent() ||
        VK[I].Value->isInstantiationDependent())
      ExprBits.InstantiationDependent = true;
    if (VK[I].EllipsisLoc.isInvalid() &&
        (VK[I].Key->containsUnexpandedParameterPack() ||
         VK[I].Value->containsUnexpandedParameterPack()))
      ExprBits.ContainsUnexpandedParameterPack = true;

    KeyValues[I].Key = VK[I].Key;
    KeyValues[I].Value = VK[I].Value;
    if (Expansions) {
      Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
      if (VK[I].NumExpansions)
        Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
      else
        Expansions[I].NumExpansionsPlusOne = 0;
    }
  }
}

ObjCDictionaryLiteral *
ObjCDictionaryLiteral::Create(const ASTContext &C,
                              ArrayRef<ObjCDictionaryElement> VK,
                              bool HasPackExpansions, QualType T,
                              ObjCMethodDecl *method, SourceRange SR) {
  void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
      VK.size(), HasPackExpansions ? VK.size() : 0));
  return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
}

ObjCDictionaryLiteral *
ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
                                   bool HasPackExpansions) {
  void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
      NumElements, HasPackExpansions ? NumElements : 0));
  return new (Mem)
      ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
}

QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {
  if (isClassReceiver())
    return ctx.getObjCInterfaceType(getClassReceiver());

  if (isSuperReceiver())
    return getSuperReceiverType();

  return getBase()->getType();
}

ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
                                 SourceLocation LBracLoc,
                                 SourceLocation SuperLoc, bool IsInstanceSuper,
                                 QualType SuperType, Selector Sel,
                                 ArrayRef<SourceLocation> SelLocs,
                                 SelectorLocationsKind SelLocsK,
                                 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
                                 SourceLocation RBracLoc, bool isImplicit)
    : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
           /*TypeDependent=*/false, /*ValueDependent=*/false,
           /*InstantiationDependent=*/false,
           /*ContainsUnexpandedParameterPack=*/false),
      SelectorOrMethod(
          reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
      Kind(IsInstanceSuper ? SuperInstance : SuperClass),
      HasMethod(Method != nullptr), IsDelegateInitCall(false),
      IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
      RBracLoc(RBracLoc) {
  initArgsAndSelLocs(Args, SelLocs, SelLocsK);
  setReceiverPointer(SuperType.getAsOpaquePtr());
}

ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
                                 SourceLocation LBracLoc,
                                 TypeSourceInfo *Receiver, Selector Sel,
                                 ArrayRef<SourceLocation> SelLocs,
                                 SelectorLocationsKind SelLocsK,
                                 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
                                 SourceLocation RBracLoc, bool isImplicit)
    : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(),
           T->isDependentType(), T->isInstantiationDependentType(),
           T->containsUnexpandedParameterPack()),
      SelectorOrMethod(
          reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
      Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),
      IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
  initArgsAndSelLocs(Args, SelLocs, SelLocsK);
  setReceiverPointer(Receiver);
}

ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
                                 SourceLocation LBracLoc, Expr *Receiver,
                                 Selector Sel, ArrayRef<SourceLocation> SelLocs,
                                 SelectorLocationsKind SelLocsK,
                                 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
                                 SourceLocation RBracLoc, bool isImplicit)
    : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
           Receiver->isTypeDependent(), Receiver->isTypeDependent(),
           Receiver->isInstantiationDependent(),
           Receiver->containsUnexpandedParameterPack()),
      SelectorOrMethod(
          reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
      Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),
      IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
  initArgsAndSelLocs(Args, SelLocs, SelLocsK);
  setReceiverPointer(Receiver);
}

void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
                                         ArrayRef<SourceLocation> SelLocs,
                                         SelectorLocationsKind SelLocsK) {
  setNumArgs(Args.size());
  Expr **MyArgs = getArgs();
  for (unsigned I = 0; I != Args.size(); ++I) {
    if (Args[I]->isTypeDependent())
      ExprBits.TypeDependent = true;
    if (Args[I]->isValueDependent())
      ExprBits.ValueDependent = true;
    if (Args[I]->isInstantiationDependent())
      ExprBits.InstantiationDependent = true;
    if (Args[I]->containsUnexpandedParameterPack())
      ExprBits.ContainsUnexpandedParameterPack = true;

    MyArgs[I] = Args[I];
  }

  SelLocsKind = SelLocsK;
  if (!isImplicit()) {
    if (SelLocsK == SelLoc_NonStandard)
      std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
  }
}

ObjCMessageExpr *
ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
                        SourceLocation LBracLoc, SourceLocation SuperLoc,
                        bool IsInstanceSuper, QualType SuperType, Selector Sel,
                        ArrayRef<SourceLocation> SelLocs,
                        ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
                        SourceLocation RBracLoc, bool isImplicit) {
  assert((!SelLocs.empty() || isImplicit) &&
         "No selector locs for non-implicit message");
  ObjCMessageExpr *Mem;
  SelectorLocationsKind SelLocsK = SelectorLocationsKind();
  if (isImplicit)
    Mem = alloc(Context, Args.size(), 0);
  else
    Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
  return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
                                   SuperType, Sel, SelLocs, SelLocsK, Method,
                                   Args, RBracLoc, isImplicit);
}

ObjCMessageExpr *
ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
                        SourceLocation LBracLoc, TypeSourceInfo *Receiver,
                        Selector Sel, ArrayRef<SourceLocation> SelLocs,
                        ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
                        SourceLocation RBracLoc, bool isImplicit) {
  assert((!SelLocs.empty() || isImplicit) &&
         "No selector locs for non-implicit message");
  ObjCMessageExpr *Mem;
  SelectorLocationsKind SelLocsK = SelectorLocationsKind();
  if (isImplicit)
    Mem = alloc(Context, Args.size(), 0);
  else
    Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
  return new (Mem)
      ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
                      Args, RBracLoc, isImplicit);
}

ObjCMessageExpr *
ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
                        SourceLocation LBracLoc, Expr *Receiver, Selector Sel,
                        ArrayRef<SourceLocation> SelLocs,
                        ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
                        SourceLocation RBracLoc, bool isImplicit) {
  assert((!SelLocs.empty() || isImplicit) &&
         "No selector locs for non-implicit message");
  ObjCMessageExpr *Mem;
  SelectorLocationsKind SelLocsK = SelectorLocationsKind();
  if (isImplicit)
    Mem = alloc(Context, Args.size(), 0);
  else
    Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
  return new (Mem)
      ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
                      Args, RBracLoc, isImplicit);
}

ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
                                              unsigned NumArgs,
                                              unsigned NumStoredSelLocs) {
  ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
  return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
}

ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
                                        ArrayRef<Expr *> Args,
                                        SourceLocation RBraceLoc,
                                        ArrayRef<SourceLocation> SelLocs,
                                        Selector Sel,
                                        SelectorLocationsKind &SelLocsK) {
  SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
  unsigned NumStoredSelLocs =
      (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
  return alloc(C, Args.size(), NumStoredSelLocs);
}

ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
                                        unsigned NumStoredSelLocs) {
  return (ObjCMessageExpr *)C.Allocate(
      totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
      alignof(ObjCMessageExpr));
}

void ObjCMessageExpr::getSelectorLocs(
    SmallVectorImpl<SourceLocation> &SelLocs) const {
  for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
    SelLocs.push_back(getSelectorLoc(i));
}


QualType ObjCMessageExpr::getCallReturnType(ASTContext &Ctx) const {
  if (const ObjCMethodDecl *MD = getMethodDecl()) {
    QualType QT = MD->getReturnType();
    if (QT == Ctx.getObjCInstanceType()) {
      // instancetype corresponds to expression types.
      return getType();
    }
    return QT;
  }

  // Expression type might be different from an expected call return type,
  // as expression type would never be a reference even if call returns a
  // reference. Reconstruct the original expression type.
  QualType QT = getType();
  switch (getValueKind()) {
  case VK_LValue:
    return Ctx.getLValueReferenceType(QT);
  case VK_XValue:
    return Ctx.getRValueReferenceType(QT);
  case VK_RValue:
    return QT;
  }
  llvm_unreachable("Unsupported ExprValueKind");
}

SourceRange ObjCMessageExpr::getReceiverRange() const {
  switch (getReceiverKind()) {
  case Instance:
    return getInstanceReceiver()->getSourceRange();

  case Class:
    return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();

  case SuperInstance:
  case SuperClass:
    return getSuperLoc();
  }

  llvm_unreachable("Invalid ReceiverKind!");
}

Selector ObjCMessageExpr::getSelector() const {
  if (HasMethod)
    return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
        ->getSelector();
  return Selector(SelectorOrMethod);
}

QualType ObjCMessageExpr::getReceiverType() const {
  switch (getReceiverKind()) {
  case Instance:
    return getInstanceReceiver()->getType();
  case Class:
    return getClassReceiver();
  case SuperInstance:
  case SuperClass:
    return getSuperType();
  }

  llvm_unreachable("unexpected receiver kind");
}

ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
  QualType T = getReceiverType();

  if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
    return Ptr->getInterfaceDecl();

  if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
    return Ty->getInterface();

  return nullptr;
}

Stmt::child_range ObjCMessageExpr::children() {
  Stmt **begin;
  if (getReceiverKind() == Instance)
    begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
  else
    begin = reinterpret_cast<Stmt **>(getArgs());
  return child_range(begin,
                     reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
}

Stmt::const_child_range ObjCMessageExpr::children() const {
  auto Children = const_cast<ObjCMessageExpr *>(this)->children();
  return const_child_range(Children.begin(), Children.end());
}

StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
  switch (getBridgeKind()) {
  case OBC_Bridge:
    return "__bridge";
  case OBC_BridgeTransfer:
    return "__bridge_transfer";
  case OBC_BridgeRetained:
    return "__bridge_retained";
  }

  llvm_unreachable("Invalid BridgeKind!");
}
