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
18using namespace clang;
19
20ObjCArrayLiteral::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
38ObjCArrayLiteral *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
47ObjCArrayLiteral *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
55ObjCDictionaryLiteral::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
89ObjCDictionaryLiteral *
90ObjCDictionaryLiteral::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
103ObjCDictionaryLiteral *
104ObjCDictionaryLiteral::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
115QualType 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
125ObjCSubscriptRefExpr *
126ObjCSubscriptRefExpr::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
134ObjCMessageExpr::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
156ObjCMessageExpr::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
174ObjCMessageExpr::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
192void 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
217ObjCMessageExpr *
218ObjCMessageExpr::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
237ObjCMessageExpr *
238ObjCMessageExpr::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
256ObjCMessageExpr *
257ObjCMessageExpr::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
275ObjCMessageExpr *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
282ObjCMessageExpr *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
294ObjCMessageExpr *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
303void 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
309SourceRange 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
325Selector ObjCMessageExpr::getSelector() const {
326  if (HasMethod)
327    return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
328        ->getSelector();
329  return Selector(SelectorOrMethod);
330}
331
332QualType 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
346ObjCInterfaceDecl *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
358Stmt::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
368StringRef 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