1292920Sdim//===--- ExprObjC.cpp - (ObjC) Expression AST Node Implementation ---------===//
2292920Sdim//
3292920Sdim//                     The LLVM Compiler Infrastructure
4292920Sdim//
5292920Sdim// This file is distributed under the University of Illinois Open Source
6292920Sdim// License. See LICENSE.TXT for details.
7292920Sdim//
8292920Sdim//===----------------------------------------------------------------------===//
9292920Sdim//
10292920Sdim// This file implements the subclesses of Expr class declared in ExprObjC.h
11292920Sdim//
12292920Sdim//===----------------------------------------------------------------------===//
13292920Sdim
14292920Sdim#include "clang/AST/ExprObjC.h"
15292920Sdim
16292920Sdim#include "clang/AST/ASTContext.h"
17292920Sdim
18292920Sdimusing namespace clang;
19292920Sdim
20292920SdimObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,
21292920Sdim                                   ObjCMethodDecl *Method, SourceRange SR)
22292920Sdim    : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
23292920Sdim           false, false),
24292920Sdim      NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {
25292920Sdim  Expr **SaveElements = getElements();
26292920Sdim  for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
27292920Sdim    if (Elements[I]->isTypeDependent() || Elements[I]->isValueDependent())
28292920Sdim      ExprBits.ValueDependent = true;
29292920Sdim    if (Elements[I]->isInstantiationDependent())
30292920Sdim      ExprBits.InstantiationDependent = true;
31292920Sdim    if (Elements[I]->containsUnexpandedParameterPack())
32292920Sdim      ExprBits.ContainsUnexpandedParameterPack = true;
33292920Sdim
34292920Sdim    SaveElements[I] = Elements[I];
35292920Sdim  }
36292920Sdim}
37292920Sdim
38292920SdimObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
39292920Sdim                                           ArrayRef<Expr *> Elements,
40292920Sdim                                           QualType T, ObjCMethodDecl *Method,
41292920Sdim                                           SourceRange SR) {
42293266Sdim  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
43292920Sdim  return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
44292920Sdim}
45292920Sdim
46292920SdimObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
47292920Sdim                                                unsigned NumElements) {
48292920Sdim
49293266Sdim  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
50292920Sdim  return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
51292920Sdim}
52292920Sdim
53292920SdimObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
54292920Sdim                                             bool HasPackExpansions, QualType T,
55292920Sdim                                             ObjCMethodDecl *method,
56292920Sdim                                             SourceRange SR)
57292920Sdim    : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
58292920Sdim           false, false),
59292920Sdim      NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
60292920Sdim      DictWithObjectsMethod(method) {
61293266Sdim  KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();
62293266Sdim  ExpansionData *Expansions =
63293266Sdim      HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr;
64292920Sdim  for (unsigned I = 0; I < NumElements; I++) {
65292920Sdim    if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() ||
66292920Sdim        VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent())
67292920Sdim      ExprBits.ValueDependent = true;
68292920Sdim    if (VK[I].Key->isInstantiationDependent() ||
69292920Sdim        VK[I].Value->isInstantiationDependent())
70292920Sdim      ExprBits.InstantiationDependent = true;
71292920Sdim    if (VK[I].EllipsisLoc.isInvalid() &&
72292920Sdim        (VK[I].Key->containsUnexpandedParameterPack() ||
73292920Sdim         VK[I].Value->containsUnexpandedParameterPack()))
74292920Sdim      ExprBits.ContainsUnexpandedParameterPack = true;
75292920Sdim
76292920Sdim    KeyValues[I].Key = VK[I].Key;
77292920Sdim    KeyValues[I].Value = VK[I].Value;
78292920Sdim    if (Expansions) {
79292920Sdim      Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
80292920Sdim      if (VK[I].NumExpansions)
81292920Sdim        Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
82292920Sdim      else
83292920Sdim        Expansions[I].NumExpansionsPlusOne = 0;
84292920Sdim    }
85292920Sdim  }
86292920Sdim}
87292920Sdim
88292920SdimObjCDictionaryLiteral *
89292920SdimObjCDictionaryLiteral::Create(const ASTContext &C,
90292920Sdim                              ArrayRef<ObjCDictionaryElement> VK,
91292920Sdim                              bool HasPackExpansions, QualType T,
92292920Sdim                              ObjCMethodDecl *method, SourceRange SR) {
93293266Sdim  void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
94293266Sdim      VK.size(), HasPackExpansions ? VK.size() : 0));
95292920Sdim  return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
96292920Sdim}
97292920Sdim
98292920SdimObjCDictionaryLiteral *
99292920SdimObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
100292920Sdim                                   bool HasPackExpansions) {
101293266Sdim  void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
102293266Sdim      NumElements, HasPackExpansions ? NumElements : 0));
103292920Sdim  return new (Mem)
104292920Sdim      ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
105292920Sdim}
106292920Sdim
107292920SdimQualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {
108292920Sdim  if (isClassReceiver())
109292920Sdim    return ctx.getObjCInterfaceType(getClassReceiver());
110292920Sdim
111292920Sdim  if (isSuperReceiver())
112292920Sdim    return getSuperReceiverType();
113292920Sdim
114292920Sdim  return getBase()->getType();
115292920Sdim}
116292920Sdim
117292920SdimObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
118292920Sdim                                 SourceLocation LBracLoc,
119292920Sdim                                 SourceLocation SuperLoc, bool IsInstanceSuper,
120292920Sdim                                 QualType SuperType, Selector Sel,
121292920Sdim                                 ArrayRef<SourceLocation> SelLocs,
122292920Sdim                                 SelectorLocationsKind SelLocsK,
123292920Sdim                                 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
124292920Sdim                                 SourceLocation RBracLoc, bool isImplicit)
125292920Sdim    : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
126292920Sdim           /*TypeDependent=*/false, /*ValueDependent=*/false,
127292920Sdim           /*InstantiationDependent=*/false,
128292920Sdim           /*ContainsUnexpandedParameterPack=*/false),
129292920Sdim      SelectorOrMethod(
130292920Sdim          reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
131292920Sdim      Kind(IsInstanceSuper ? SuperInstance : SuperClass),
132292920Sdim      HasMethod(Method != nullptr), IsDelegateInitCall(false),
133292920Sdim      IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
134292920Sdim      RBracLoc(RBracLoc) {
135292920Sdim  initArgsAndSelLocs(Args, SelLocs, SelLocsK);
136292920Sdim  setReceiverPointer(SuperType.getAsOpaquePtr());
137292920Sdim}
138292920Sdim
139292920SdimObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
140292920Sdim                                 SourceLocation LBracLoc,
141292920Sdim                                 TypeSourceInfo *Receiver, Selector Sel,
142292920Sdim                                 ArrayRef<SourceLocation> SelLocs,
143292920Sdim                                 SelectorLocationsKind SelLocsK,
144292920Sdim                                 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
145292920Sdim                                 SourceLocation RBracLoc, bool isImplicit)
146292920Sdim    : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(),
147292920Sdim           T->isDependentType(), T->isInstantiationDependentType(),
148292920Sdim           T->containsUnexpandedParameterPack()),
149292920Sdim      SelectorOrMethod(
150292920Sdim          reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
151292920Sdim      Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),
152292920Sdim      IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
153292920Sdim  initArgsAndSelLocs(Args, SelLocs, SelLocsK);
154292920Sdim  setReceiverPointer(Receiver);
155292920Sdim}
156292920Sdim
157292920SdimObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
158292920Sdim                                 SourceLocation LBracLoc, Expr *Receiver,
159292920Sdim                                 Selector Sel, ArrayRef<SourceLocation> SelLocs,
160292920Sdim                                 SelectorLocationsKind SelLocsK,
161292920Sdim                                 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
162292920Sdim                                 SourceLocation RBracLoc, bool isImplicit)
163292920Sdim    : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
164292920Sdim           Receiver->isTypeDependent(), Receiver->isTypeDependent(),
165292920Sdim           Receiver->isInstantiationDependent(),
166292920Sdim           Receiver->containsUnexpandedParameterPack()),
167292920Sdim      SelectorOrMethod(
168292920Sdim          reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
169292920Sdim      Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),
170292920Sdim      IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
171292920Sdim  initArgsAndSelLocs(Args, SelLocs, SelLocsK);
172292920Sdim  setReceiverPointer(Receiver);
173292920Sdim}
174292920Sdim
175292920Sdimvoid ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
176292920Sdim                                         ArrayRef<SourceLocation> SelLocs,
177292920Sdim                                         SelectorLocationsKind SelLocsK) {
178292920Sdim  setNumArgs(Args.size());
179292920Sdim  Expr **MyArgs = getArgs();
180292920Sdim  for (unsigned I = 0; I != Args.size(); ++I) {
181292920Sdim    if (Args[I]->isTypeDependent())
182292920Sdim      ExprBits.TypeDependent = true;
183292920Sdim    if (Args[I]->isValueDependent())
184292920Sdim      ExprBits.ValueDependent = true;
185292920Sdim    if (Args[I]->isInstantiationDependent())
186292920Sdim      ExprBits.InstantiationDependent = true;
187292920Sdim    if (Args[I]->containsUnexpandedParameterPack())
188292920Sdim      ExprBits.ContainsUnexpandedParameterPack = true;
189292920Sdim
190292920Sdim    MyArgs[I] = Args[I];
191292920Sdim  }
192292920Sdim
193292920Sdim  SelLocsKind = SelLocsK;
194292920Sdim  if (!isImplicit()) {
195292920Sdim    if (SelLocsK == SelLoc_NonStandard)
196292920Sdim      std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
197292920Sdim  }
198292920Sdim}
199292920Sdim
200292920SdimObjCMessageExpr *
201292920SdimObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
202292920Sdim                        SourceLocation LBracLoc, SourceLocation SuperLoc,
203292920Sdim                        bool IsInstanceSuper, QualType SuperType, Selector Sel,
204292920Sdim                        ArrayRef<SourceLocation> SelLocs,
205292920Sdim                        ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
206292920Sdim                        SourceLocation RBracLoc, bool isImplicit) {
207292920Sdim  assert((!SelLocs.empty() || isImplicit) &&
208292920Sdim         "No selector locs for non-implicit message");
209292920Sdim  ObjCMessageExpr *Mem;
210292920Sdim  SelectorLocationsKind SelLocsK = SelectorLocationsKind();
211292920Sdim  if (isImplicit)
212292920Sdim    Mem = alloc(Context, Args.size(), 0);
213292920Sdim  else
214292920Sdim    Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
215292920Sdim  return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
216292920Sdim                                   SuperType, Sel, SelLocs, SelLocsK, Method,
217292920Sdim                                   Args, RBracLoc, isImplicit);
218292920Sdim}
219292920Sdim
220292920SdimObjCMessageExpr *
221292920SdimObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
222292920Sdim                        SourceLocation LBracLoc, TypeSourceInfo *Receiver,
223292920Sdim                        Selector Sel, ArrayRef<SourceLocation> SelLocs,
224292920Sdim                        ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
225292920Sdim                        SourceLocation RBracLoc, bool isImplicit) {
226292920Sdim  assert((!SelLocs.empty() || isImplicit) &&
227292920Sdim         "No selector locs for non-implicit message");
228292920Sdim  ObjCMessageExpr *Mem;
229292920Sdim  SelectorLocationsKind SelLocsK = SelectorLocationsKind();
230292920Sdim  if (isImplicit)
231292920Sdim    Mem = alloc(Context, Args.size(), 0);
232292920Sdim  else
233292920Sdim    Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
234292920Sdim  return new (Mem)
235292920Sdim      ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
236292920Sdim                      Args, RBracLoc, isImplicit);
237292920Sdim}
238292920Sdim
239292920SdimObjCMessageExpr *
240292920SdimObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
241292920Sdim                        SourceLocation LBracLoc, Expr *Receiver, Selector Sel,
242292920Sdim                        ArrayRef<SourceLocation> SelLocs,
243292920Sdim                        ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
244292920Sdim                        SourceLocation RBracLoc, bool isImplicit) {
245292920Sdim  assert((!SelLocs.empty() || isImplicit) &&
246292920Sdim         "No selector locs for non-implicit message");
247292920Sdim  ObjCMessageExpr *Mem;
248292920Sdim  SelectorLocationsKind SelLocsK = SelectorLocationsKind();
249292920Sdim  if (isImplicit)
250292920Sdim    Mem = alloc(Context, Args.size(), 0);
251292920Sdim  else
252292920Sdim    Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
253292920Sdim  return new (Mem)
254292920Sdim      ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
255292920Sdim                      Args, RBracLoc, isImplicit);
256292920Sdim}
257292920Sdim
258292920SdimObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
259292920Sdim                                              unsigned NumArgs,
260292920Sdim                                              unsigned NumStoredSelLocs) {
261292920Sdim  ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
262292920Sdim  return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
263292920Sdim}
264292920Sdim
265292920SdimObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
266292920Sdim                                        ArrayRef<Expr *> Args,
267292920Sdim                                        SourceLocation RBraceLoc,
268292920Sdim                                        ArrayRef<SourceLocation> SelLocs,
269292920Sdim                                        Selector Sel,
270292920Sdim                                        SelectorLocationsKind &SelLocsK) {
271292920Sdim  SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
272292920Sdim  unsigned NumStoredSelLocs =
273292920Sdim      (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
274292920Sdim  return alloc(C, Args.size(), NumStoredSelLocs);
275292920Sdim}
276292920Sdim
277292920SdimObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
278292920Sdim                                        unsigned NumStoredSelLocs) {
279292920Sdim  return (ObjCMessageExpr *)C.Allocate(
280293266Sdim      totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
281293266Sdim      llvm::AlignOf<ObjCMessageExpr>::Alignment);
282292920Sdim}
283292920Sdim
284292920Sdimvoid ObjCMessageExpr::getSelectorLocs(
285292920Sdim    SmallVectorImpl<SourceLocation> &SelLocs) const {
286292920Sdim  for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
287292920Sdim    SelLocs.push_back(getSelectorLoc(i));
288292920Sdim}
289292920Sdim
290292920SdimSourceRange ObjCMessageExpr::getReceiverRange() const {
291292920Sdim  switch (getReceiverKind()) {
292292920Sdim  case Instance:
293292920Sdim    return getInstanceReceiver()->getSourceRange();
294292920Sdim
295292920Sdim  case Class:
296292920Sdim    return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
297292920Sdim
298292920Sdim  case SuperInstance:
299292920Sdim  case SuperClass:
300292920Sdim    return getSuperLoc();
301292920Sdim  }
302292920Sdim
303292920Sdim  llvm_unreachable("Invalid ReceiverKind!");
304292920Sdim}
305292920Sdim
306292920SdimSelector ObjCMessageExpr::getSelector() const {
307292920Sdim  if (HasMethod)
308292920Sdim    return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
309292920Sdim        ->getSelector();
310292920Sdim  return Selector(SelectorOrMethod);
311292920Sdim}
312292920Sdim
313292920SdimQualType ObjCMessageExpr::getReceiverType() const {
314292920Sdim  switch (getReceiverKind()) {
315292920Sdim  case Instance:
316292920Sdim    return getInstanceReceiver()->getType();
317292920Sdim  case Class:
318292920Sdim    return getClassReceiver();
319292920Sdim  case SuperInstance:
320292920Sdim  case SuperClass:
321292920Sdim    return getSuperType();
322292920Sdim  }
323292920Sdim
324292920Sdim  llvm_unreachable("unexpected receiver kind");
325292920Sdim}
326292920Sdim
327292920SdimObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
328292920Sdim  QualType T = getReceiverType();
329292920Sdim
330292920Sdim  if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
331292920Sdim    return Ptr->getInterfaceDecl();
332292920Sdim
333292920Sdim  if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
334292920Sdim    return Ty->getInterface();
335292920Sdim
336292920Sdim  return nullptr;
337292920Sdim}
338292920Sdim
339292920SdimStmt::child_range ObjCMessageExpr::children() {
340292920Sdim  Stmt **begin;
341292920Sdim  if (getReceiverKind() == Instance)
342293266Sdim    begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
343292920Sdim  else
344292920Sdim    begin = reinterpret_cast<Stmt **>(getArgs());
345292920Sdim  return child_range(begin,
346292920Sdim                     reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
347292920Sdim}
348292920Sdim
349292920SdimStringRef ObjCBridgedCastExpr::getBridgeKindName() const {
350292920Sdim  switch (getBridgeKind()) {
351292920Sdim  case OBC_Bridge:
352292920Sdim    return "__bridge";
353292920Sdim  case OBC_BridgeTransfer:
354292920Sdim    return "__bridge_transfer";
355292920Sdim  case OBC_BridgeRetained:
356292920Sdim    return "__bridge_retained";
357292920Sdim  }
358292920Sdim
359292920Sdim  llvm_unreachable("Invalid BridgeKind!");
360292920Sdim}
361