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