• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ObjCArrayLiteral(ArrayRef<Expr * > Elements,QualType T,ObjCMethodDecl * Method,SourceRange SR)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 
Create(const ASTContext & C,ArrayRef<Expr * > Elements,QualType T,ObjCMethodDecl * Method,SourceRange SR)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 
CreateEmpty(const ASTContext & C,unsigned NumElements)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 
ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,bool HasPackExpansions,QualType T,ObjCMethodDecl * method,SourceRange SR)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 *
Create(const ASTContext & C,ArrayRef<ObjCDictionaryElement> VK,bool HasPackExpansions,QualType T,ObjCMethodDecl * method,SourceRange SR)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 *
CreateEmpty(const ASTContext & C,unsigned NumElements,bool HasPackExpansions)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 
getReceiverType(const ASTContext & ctx) const115 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 *
Create(const ASTContext & C,Expr * base,Expr * key,QualType T,ObjCMethodDecl * getMethod,ObjCMethodDecl * setMethod,SourceLocation RB)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 
ObjCMessageExpr(QualType T,ExprValueKind VK,SourceLocation LBracLoc,SourceLocation SuperLoc,bool IsInstanceSuper,QualType SuperType,Selector Sel,ArrayRef<SourceLocation> SelLocs,SelectorLocationsKind SelLocsK,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)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 
ObjCMessageExpr(QualType T,ExprValueKind VK,SourceLocation LBracLoc,TypeSourceInfo * Receiver,Selector Sel,ArrayRef<SourceLocation> SelLocs,SelectorLocationsKind SelLocsK,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)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 
ObjCMessageExpr(QualType T,ExprValueKind VK,SourceLocation LBracLoc,Expr * Receiver,Selector Sel,ArrayRef<SourceLocation> SelLocs,SelectorLocationsKind SelLocsK,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)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 
initArgsAndSelLocs(ArrayRef<Expr * > Args,ArrayRef<SourceLocation> SelLocs,SelectorLocationsKind SelLocsK)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 *
Create(const ASTContext & Context,QualType T,ExprValueKind VK,SourceLocation LBracLoc,SourceLocation SuperLoc,bool IsInstanceSuper,QualType SuperType,Selector Sel,ArrayRef<SourceLocation> SelLocs,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)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 *
Create(const ASTContext & Context,QualType T,ExprValueKind VK,SourceLocation LBracLoc,TypeSourceInfo * Receiver,Selector Sel,ArrayRef<SourceLocation> SelLocs,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)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 *
Create(const ASTContext & Context,QualType T,ExprValueKind VK,SourceLocation LBracLoc,Expr * Receiver,Selector Sel,ArrayRef<SourceLocation> SelLocs,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)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 
CreateEmpty(const ASTContext & Context,unsigned NumArgs,unsigned NumStoredSelLocs)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 
alloc(const ASTContext & C,ArrayRef<Expr * > Args,SourceLocation RBraceLoc,ArrayRef<SourceLocation> SelLocs,Selector Sel,SelectorLocationsKind & SelLocsK)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 
alloc(const ASTContext & C,unsigned NumArgs,unsigned NumStoredSelLocs)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 
getSelectorLocs(SmallVectorImpl<SourceLocation> & SelLocs) const303 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 
getReceiverRange() const309 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 
getSelector() const325 Selector ObjCMessageExpr::getSelector() const {
326   if (HasMethod)
327     return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
328         ->getSelector();
329   return Selector(SelectorOrMethod);
330 }
331 
getReceiverType() const332 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 
getReceiverInterface() const346 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 
children()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 
getBridgeKindName() const368 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