blob: 0936a81a597a09ae0e419a42ee12d2330f24ea8f [file] [log] [blame]
James Y Knight4b7a5e72015-09-29 22:28:44 +00001//===--- 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) {
James Y Knight6c2f06b2015-12-31 04:43:19 +000042 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
James Y Knight4b7a5e72015-09-29 22:28:44 +000043 return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
44}
45
46ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
47 unsigned NumElements) {
48
James Y Knight6c2f06b2015-12-31 04:43:19 +000049 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
James Y Knight4b7a5e72015-09-29 22:28:44 +000050 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) {
James Y Knight6c2f06b2015-12-31 04:43:19 +000061 KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();
James Y Knightdb8cdd32015-12-31 06:01:19 +000062 ExpansionData *Expansions =
63 HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr;
James Y Knight4b7a5e72015-09-29 22:28:44 +000064 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) {
James Y Knight6c2f06b2015-12-31 04:43:19 +000093 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
94 VK.size(), HasPackExpansions ? VK.size() : 0));
James Y Knight4b7a5e72015-09-29 22:28:44 +000095 return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
96}
97
98ObjCDictionaryLiteral *
99ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
100 bool HasPackExpansions) {
James Y Knight6c2f06b2015-12-31 04:43:19 +0000101 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
102 NumElements, HasPackExpansions ? NumElements : 0));
James Y Knight4b7a5e72015-09-29 22:28:44 +0000103 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
James Y Knight4b7a5e72015-09-29 22:28:44 +0000117ObjCMessageExpr::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) {
James Y Knight4b7a5e72015-09-29 22:28:44 +0000279 return (ObjCMessageExpr *)C.Allocate(
James Y Knight6c2f06b2015-12-31 04:43:19 +0000280 totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
281 llvm::AlignOf<ObjCMessageExpr>::Alignment);
James Y Knight4b7a5e72015-09-29 22:28:44 +0000282}
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)
James Y Knight6c2f06b2015-12-31 04:43:19 +0000342 begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
James Y Knight4b7a5e72015-09-29 22:28:44 +0000343 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}