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 = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
     43   return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
     44 }
     45 
     46 ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
     47                                                 unsigned NumElements) {
     48 
     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, false, false,
     58            false, false),
     59       NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
     60       DictWithObjectsMethod(method) {
     61   KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();
     62   ExpansionData *Expansions =
     63       HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr;
     64   for (unsigned I = 0; I < NumElements; I++) {
     65     if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() ||
     66         VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent())
     67       ExprBits.ValueDependent = true;
     68     if (VK[I].Key->isInstantiationDependent() ||
     69         VK[I].Value->isInstantiationDependent())
     70       ExprBits.InstantiationDependent = true;
     71     if (VK[I].EllipsisLoc.isInvalid() &&
     72         (VK[I].Key->containsUnexpandedParameterPack() ||
     73          VK[I].Value->containsUnexpandedParameterPack()))
     74       ExprBits.ContainsUnexpandedParameterPack = true;
     75 
     76     KeyValues[I].Key = VK[I].Key;
     77     KeyValues[I].Value = VK[I].Value;
     78     if (Expansions) {
     79       Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
     80       if (VK[I].NumExpansions)
     81         Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
     82       else
     83         Expansions[I].NumExpansionsPlusOne = 0;
     84     }
     85   }
     86 }
     87 
     88 ObjCDictionaryLiteral *
     89 ObjCDictionaryLiteral::Create(const ASTContext &C,
     90                               ArrayRef<ObjCDictionaryElement> VK,
     91                               bool HasPackExpansions, QualType T,
     92                               ObjCMethodDecl *method, SourceRange SR) {
     93   void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
     94       VK.size(), HasPackExpansions ? VK.size() : 0));
     95   return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
     96 }
     97 
     98 ObjCDictionaryLiteral *
     99 ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
    100                                    bool HasPackExpansions) {
    101   void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
    102       NumElements, HasPackExpansions ? NumElements : 0));
    103   return new (Mem)
    104       ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
    105 }
    106 
    107 QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {
    108   if (isClassReceiver())
    109     return ctx.getObjCInterfaceType(getClassReceiver());
    110 
    111   if (isSuperReceiver())
    112     return getSuperReceiverType();
    113 
    114   return getBase()->getType();
    115 }
    116 
    117 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
    118                                  SourceLocation LBracLoc,
    119                                  SourceLocation SuperLoc, bool IsInstanceSuper,
    120                                  QualType SuperType, Selector Sel,
    121                                  ArrayRef<SourceLocation> SelLocs,
    122                                  SelectorLocationsKind SelLocsK,
    123                                  ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
    124                                  SourceLocation RBracLoc, bool isImplicit)
    125     : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
    126            /*TypeDependent=*/false, /*ValueDependent=*/false,
    127            /*InstantiationDependent=*/false,
    128            /*ContainsUnexpandedParameterPack=*/false),
    129       SelectorOrMethod(
    130           reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
    131       Kind(IsInstanceSuper ? SuperInstance : SuperClass),
    132       HasMethod(Method != nullptr), IsDelegateInitCall(false),
    133       IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
    134       RBracLoc(RBracLoc) {
    135   initArgsAndSelLocs(Args, SelLocs, SelLocsK);
    136   setReceiverPointer(SuperType.getAsOpaquePtr());
    137 }
    138 
    139 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
    140                                  SourceLocation LBracLoc,
    141                                  TypeSourceInfo *Receiver, Selector Sel,
    142                                  ArrayRef<SourceLocation> SelLocs,
    143                                  SelectorLocationsKind SelLocsK,
    144                                  ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
    145                                  SourceLocation RBracLoc, bool isImplicit)
    146     : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(),
    147            T->isDependentType(), T->isInstantiationDependentType(),
    148            T->containsUnexpandedParameterPack()),
    149       SelectorOrMethod(
    150           reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
    151       Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),
    152       IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
    153   initArgsAndSelLocs(Args, SelLocs, SelLocsK);
    154   setReceiverPointer(Receiver);
    155 }
    156 
    157 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
    158                                  SourceLocation LBracLoc, Expr *Receiver,
    159                                  Selector Sel, ArrayRef<SourceLocation> SelLocs,
    160                                  SelectorLocationsKind SelLocsK,
    161                                  ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
    162                                  SourceLocation RBracLoc, bool isImplicit)
    163     : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
    164            Receiver->isTypeDependent(), Receiver->isTypeDependent(),
    165            Receiver->isInstantiationDependent(),
    166            Receiver->containsUnexpandedParameterPack()),
    167       SelectorOrMethod(
    168           reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
    169       Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),
    170       IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
    171   initArgsAndSelLocs(Args, SelLocs, SelLocsK);
    172   setReceiverPointer(Receiver);
    173 }
    174 
    175 void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
    176                                          ArrayRef<SourceLocation> SelLocs,
    177                                          SelectorLocationsKind SelLocsK) {
    178   setNumArgs(Args.size());
    179   Expr **MyArgs = getArgs();
    180   for (unsigned I = 0; I != Args.size(); ++I) {
    181     if (Args[I]->isTypeDependent())
    182       ExprBits.TypeDependent = true;
    183     if (Args[I]->isValueDependent())
    184       ExprBits.ValueDependent = true;
    185     if (Args[I]->isInstantiationDependent())
    186       ExprBits.InstantiationDependent = true;
    187     if (Args[I]->containsUnexpandedParameterPack())
    188       ExprBits.ContainsUnexpandedParameterPack = true;
    189 
    190     MyArgs[I] = Args[I];
    191   }
    192 
    193   SelLocsKind = SelLocsK;
    194   if (!isImplicit()) {
    195     if (SelLocsK == SelLoc_NonStandard)
    196       std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
    197   }
    198 }
    199 
    200 ObjCMessageExpr *
    201 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
    202                         SourceLocation LBracLoc, SourceLocation SuperLoc,
    203                         bool IsInstanceSuper, QualType SuperType, Selector Sel,
    204                         ArrayRef<SourceLocation> SelLocs,
    205                         ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
    206                         SourceLocation RBracLoc, bool isImplicit) {
    207   assert((!SelLocs.empty() || isImplicit) &&
    208          "No selector locs for non-implicit message");
    209   ObjCMessageExpr *Mem;
    210   SelectorLocationsKind SelLocsK = SelectorLocationsKind();
    211   if (isImplicit)
    212     Mem = alloc(Context, Args.size(), 0);
    213   else
    214     Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
    215   return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
    216                                    SuperType, Sel, SelLocs, SelLocsK, Method,
    217                                    Args, RBracLoc, isImplicit);
    218 }
    219 
    220 ObjCMessageExpr *
    221 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
    222                         SourceLocation LBracLoc, TypeSourceInfo *Receiver,
    223                         Selector Sel, ArrayRef<SourceLocation> SelLocs,
    224                         ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
    225                         SourceLocation RBracLoc, bool isImplicit) {
    226   assert((!SelLocs.empty() || isImplicit) &&
    227          "No selector locs for non-implicit message");
    228   ObjCMessageExpr *Mem;
    229   SelectorLocationsKind SelLocsK = SelectorLocationsKind();
    230   if (isImplicit)
    231     Mem = alloc(Context, Args.size(), 0);
    232   else
    233     Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
    234   return new (Mem)
    235       ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
    236                       Args, RBracLoc, isImplicit);
    237 }
    238 
    239 ObjCMessageExpr *
    240 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
    241                         SourceLocation LBracLoc, Expr *Receiver, Selector Sel,
    242                         ArrayRef<SourceLocation> SelLocs,
    243                         ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
    244                         SourceLocation RBracLoc, bool isImplicit) {
    245   assert((!SelLocs.empty() || isImplicit) &&
    246          "No selector locs for non-implicit message");
    247   ObjCMessageExpr *Mem;
    248   SelectorLocationsKind SelLocsK = SelectorLocationsKind();
    249   if (isImplicit)
    250     Mem = alloc(Context, Args.size(), 0);
    251   else
    252     Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
    253   return new (Mem)
    254       ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
    255                       Args, RBracLoc, isImplicit);
    256 }
    257 
    258 ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
    259                                               unsigned NumArgs,
    260                                               unsigned NumStoredSelLocs) {
    261   ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
    262   return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
    263 }
    264 
    265 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
    266                                         ArrayRef<Expr *> Args,
    267                                         SourceLocation RBraceLoc,
    268                                         ArrayRef<SourceLocation> SelLocs,
    269                                         Selector Sel,
    270                                         SelectorLocationsKind &SelLocsK) {
    271   SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
    272   unsigned NumStoredSelLocs =
    273       (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
    274   return alloc(C, Args.size(), NumStoredSelLocs);
    275 }
    276 
    277 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
    278                                         unsigned NumStoredSelLocs) {
    279   return (ObjCMessageExpr *)C.Allocate(
    280       totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
    281       llvm::AlignOf<ObjCMessageExpr>::Alignment);
    282 }
    283 
    284 void ObjCMessageExpr::getSelectorLocs(
    285     SmallVectorImpl<SourceLocation> &SelLocs) const {
    286   for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
    287     SelLocs.push_back(getSelectorLoc(i));
    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 StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
    350   switch (getBridgeKind()) {
    351   case OBC_Bridge:
    352     return "__bridge";
    353   case OBC_BridgeTransfer:
    354     return "__bridge_transfer";
    355   case OBC_BridgeRetained:
    356     return "__bridge_retained";
    357   }
    358 
    359   llvm_unreachable("Invalid BridgeKind!");
    360 }
    361