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