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