brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.7 KiB · 3509182 Raw
348 lines · cpp
1//===- ExprObjC.cpp - (ObjC) Expression AST Node Implementation -----------===//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 the subclesses of Expr class declared in ExprObjC.h10//11//===----------------------------------------------------------------------===//12 13#include "clang/AST/ExprObjC.h"14#include "clang/AST/ASTContext.h"15#include "clang/AST/Attr.h"16#include "clang/AST/ComputeDependence.h"17#include "clang/AST/SelectorLocationsKind.h"18#include "clang/AST/Type.h"19#include "clang/AST/TypeLoc.h"20#include "llvm/Support/ErrorHandling.h"21#include <cassert>22#include <cstdint>23 24using namespace clang;25 26ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,27                                   ObjCMethodDecl *Method, SourceRange SR)28    : Expr(ObjCArrayLiteralClass, T, VK_PRValue, OK_Ordinary),29      NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {30  Expr **SaveElements = getElements();31  for (unsigned I = 0, N = Elements.size(); I != N; ++I)32    SaveElements[I] = Elements[I];33 34  setDependence(computeDependence(this));35}36 37ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,38                                           ArrayRef<Expr *> Elements,39                                           QualType T, ObjCMethodDecl *Method,40                                           SourceRange SR) {41  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));42  return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);43}44 45ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,46                                                unsigned NumElements) {47  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));48  return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);49}50 51ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,52                                             bool HasPackExpansions, QualType T,53                                             ObjCMethodDecl *method,54                                             SourceRange SR)55    : Expr(ObjCDictionaryLiteralClass, T, VK_PRValue, OK_Ordinary),56      NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),57      DictWithObjectsMethod(method) {58  KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();59  ExpansionData *Expansions =60      HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr;61  for (unsigned I = 0; I < NumElements; I++) {62    KeyValues[I].Key = VK[I].Key;63    KeyValues[I].Value = VK[I].Value;64    if (Expansions) {65      Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;66      if (VK[I].NumExpansions)67        Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;68      else69        Expansions[I].NumExpansionsPlusOne = 0;70    }71  }72  setDependence(computeDependence(this));73}74 75ObjCDictionaryLiteral *76ObjCDictionaryLiteral::Create(const ASTContext &C,77                              ArrayRef<ObjCDictionaryElement> VK,78                              bool HasPackExpansions, QualType T,79                              ObjCMethodDecl *method, SourceRange SR) {80  void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(81      VK.size(), HasPackExpansions ? VK.size() : 0));82  return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);83}84 85ObjCDictionaryLiteral *86ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,87                                   bool HasPackExpansions) {88  void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(89      NumElements, HasPackExpansions ? NumElements : 0));90  return new (Mem)91      ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);92}93 94QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {95  if (isClassReceiver())96    return ctx.getObjCInterfaceType(getClassReceiver());97 98  if (isSuperReceiver())99    return getSuperReceiverType();100 101  return getBase()->getType();102}103 104ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,105                                 SourceLocation LBracLoc,106                                 SourceLocation SuperLoc, bool IsInstanceSuper,107                                 QualType SuperType, Selector Sel,108                                 ArrayRef<SourceLocation> SelLocs,109                                 SelectorLocationsKind SelLocsK,110                                 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,111                                 SourceLocation RBracLoc, bool isImplicit)112    : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),113      SelectorOrMethod(114          reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),115      Kind(IsInstanceSuper ? SuperInstance : SuperClass),116      HasMethod(Method != nullptr), IsDelegateInitCall(false),117      IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),118      RBracLoc(RBracLoc) {119  initArgsAndSelLocs(Args, SelLocs, SelLocsK);120  setReceiverPointer(SuperType.getAsOpaquePtr());121  setDependence(computeDependence(this));122}123 124ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,125                                 SourceLocation LBracLoc,126                                 TypeSourceInfo *Receiver, Selector Sel,127                                 ArrayRef<SourceLocation> SelLocs,128                                 SelectorLocationsKind SelLocsK,129                                 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,130                                 SourceLocation RBracLoc, bool isImplicit)131    : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),132      SelectorOrMethod(133          reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),134      Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),135      IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {136  initArgsAndSelLocs(Args, SelLocs, SelLocsK);137  setReceiverPointer(Receiver);138  setDependence(computeDependence(this));139}140 141ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,142                                 SourceLocation LBracLoc, Expr *Receiver,143                                 Selector Sel, ArrayRef<SourceLocation> SelLocs,144                                 SelectorLocationsKind SelLocsK,145                                 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,146                                 SourceLocation RBracLoc, bool isImplicit)147    : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),148      SelectorOrMethod(149          reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),150      Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),151      IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {152  initArgsAndSelLocs(Args, SelLocs, SelLocsK);153  setReceiverPointer(Receiver);154  setDependence(computeDependence(this));155}156 157void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,158                                         ArrayRef<SourceLocation> SelLocs,159                                         SelectorLocationsKind SelLocsK) {160  setNumArgs(Args.size());161  Expr **MyArgs = getArgs();162  for (unsigned I = 0; I != Args.size(); ++I)163    MyArgs[I] = Args[I];164 165  SelLocsKind = SelLocsK;166  if (!isImplicit() && SelLocsK == SelLoc_NonStandard)167    llvm::copy(SelLocs, getStoredSelLocs());168}169 170ObjCMessageExpr *171ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,172                        SourceLocation LBracLoc, SourceLocation SuperLoc,173                        bool IsInstanceSuper, QualType SuperType, Selector Sel,174                        ArrayRef<SourceLocation> SelLocs,175                        ObjCMethodDecl *Method, ArrayRef<Expr *> Args,176                        SourceLocation RBracLoc, bool isImplicit) {177  assert((!SelLocs.empty() || isImplicit) &&178         "No selector locs for non-implicit message");179  ObjCMessageExpr *Mem;180  SelectorLocationsKind SelLocsK = SelectorLocationsKind();181  if (isImplicit)182    Mem = alloc(Context, Args.size(), 0);183  else184    Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);185  return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,186                                   SuperType, Sel, SelLocs, SelLocsK, Method,187                                   Args, RBracLoc, isImplicit);188}189 190ObjCMessageExpr *191ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,192                        SourceLocation LBracLoc, TypeSourceInfo *Receiver,193                        Selector Sel, ArrayRef<SourceLocation> SelLocs,194                        ObjCMethodDecl *Method, ArrayRef<Expr *> Args,195                        SourceLocation RBracLoc, bool isImplicit) {196  assert((!SelLocs.empty() || isImplicit) &&197         "No selector locs for non-implicit message");198  ObjCMessageExpr *Mem;199  SelectorLocationsKind SelLocsK = SelectorLocationsKind();200  if (isImplicit)201    Mem = alloc(Context, Args.size(), 0);202  else203    Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);204  return new (Mem)205      ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,206                      Args, RBracLoc, isImplicit);207}208 209ObjCMessageExpr *210ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,211                        SourceLocation LBracLoc, Expr *Receiver, Selector Sel,212                        ArrayRef<SourceLocation> SelLocs,213                        ObjCMethodDecl *Method, ArrayRef<Expr *> Args,214                        SourceLocation RBracLoc, bool isImplicit) {215  assert((!SelLocs.empty() || isImplicit) &&216         "No selector locs for non-implicit message");217  ObjCMessageExpr *Mem;218  SelectorLocationsKind SelLocsK = SelectorLocationsKind();219  if (isImplicit)220    Mem = alloc(Context, Args.size(), 0);221  else222    Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);223  return new (Mem)224      ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,225                      Args, RBracLoc, isImplicit);226}227 228ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,229                                              unsigned NumArgs,230                                              unsigned NumStoredSelLocs) {231  ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);232  return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);233}234 235ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,236                                        ArrayRef<Expr *> Args,237                                        SourceLocation RBraceLoc,238                                        ArrayRef<SourceLocation> SelLocs,239                                        Selector Sel,240                                        SelectorLocationsKind &SelLocsK) {241  SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);242  unsigned NumStoredSelLocs =243      (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;244  return alloc(C, Args.size(), NumStoredSelLocs);245}246 247ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,248                                        unsigned NumStoredSelLocs) {249  return (ObjCMessageExpr *)C.Allocate(250      totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),251      alignof(ObjCMessageExpr));252}253 254void ObjCMessageExpr::getSelectorLocs(255    SmallVectorImpl<SourceLocation> &SelLocs) const {256  for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)257    SelLocs.push_back(getSelectorLoc(i));258}259 260 261QualType ObjCMessageExpr::getCallReturnType(ASTContext &Ctx) const {262  if (const ObjCMethodDecl *MD = getMethodDecl()) {263    QualType QT = MD->getReturnType();264    if (QT == Ctx.getObjCInstanceType()) {265      // instancetype corresponds to expression types.266      return getType();267    }268    return QT;269  }270  return Ctx.getReferenceQualifiedType(this);271}272 273SourceRange ObjCMessageExpr::getReceiverRange() const {274  switch (getReceiverKind()) {275  case Instance:276    return getInstanceReceiver()->getSourceRange();277 278  case Class:279    return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();280 281  case SuperInstance:282  case SuperClass:283    return getSuperLoc();284  }285 286  llvm_unreachable("Invalid ReceiverKind!");287}288 289Selector ObjCMessageExpr::getSelector() const {290  if (HasMethod)291    return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)292        ->getSelector();293  return Selector(SelectorOrMethod);294}295 296QualType ObjCMessageExpr::getReceiverType() const {297  switch (getReceiverKind()) {298  case Instance:299    return getInstanceReceiver()->getType();300  case Class:301    return getClassReceiver();302  case SuperInstance:303  case SuperClass:304    return getSuperType();305  }306 307  llvm_unreachable("unexpected receiver kind");308}309 310ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {311  QualType T = getReceiverType();312 313  if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())314    return Ptr->getInterfaceDecl();315 316  if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())317    return Ty->getInterface();318 319  return nullptr;320}321 322Stmt::child_range ObjCMessageExpr::children() {323  Stmt **begin;324  if (getReceiverKind() == Instance)325    begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());326  else327    begin = reinterpret_cast<Stmt **>(getArgs());328  return child_range(begin,329                     reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));330}331 332Stmt::const_child_range ObjCMessageExpr::children() const {333  return const_cast<ObjCMessageExpr *>(this)->children();334}335 336StringRef ObjCBridgedCastExpr::getBridgeKindName() const {337  switch (getBridgeKind()) {338  case OBC_Bridge:339    return "__bridge";340  case OBC_BridgeTransfer:341    return "__bridge_transfer";342  case OBC_BridgeRetained:343    return "__bridge_retained";344  }345 346  llvm_unreachable("Invalid BridgeKind!");347}348