ExprObjC.cpp revision 296417
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 = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
43  return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
44}
45
46ObjCArrayLiteral *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
53ObjCDictionaryLiteral::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
88ObjCDictionaryLiteral *
89ObjCDictionaryLiteral::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
98ObjCDictionaryLiteral *
99ObjCDictionaryLiteral::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
107QualType 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
117ObjCMessageExpr::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
139ObjCMessageExpr::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
157ObjCMessageExpr::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
175void 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
200ObjCMessageExpr *
201ObjCMessageExpr::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
220ObjCMessageExpr *
221ObjCMessageExpr::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
239ObjCMessageExpr *
240ObjCMessageExpr::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
258ObjCMessageExpr *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
265ObjCMessageExpr *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
277ObjCMessageExpr *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
284void 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
290SourceRange 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
306Selector ObjCMessageExpr::getSelector() const {
307  if (HasMethod)
308    return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
309        ->getSelector();
310  return Selector(SelectorOrMethod);
311}
312
313QualType 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
327ObjCInterfaceDecl *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
339Stmt::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
349StringRef 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