150
|
1 //===- ExprObjC.cpp - (ObjC) Expression AST Node Implementation -----------===//
|
|
2 //
|
|
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
4 // See https://llvm.org/LICENSE.txt for license information.
|
|
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
6 //
|
|
7 //===----------------------------------------------------------------------===//
|
|
8 //
|
|
9 // This file implements the subclesses of Expr class declared in ExprObjC.h
|
|
10 //
|
|
11 //===----------------------------------------------------------------------===//
|
|
12
|
|
13 #include "clang/AST/ExprObjC.h"
|
|
14 #include "clang/AST/ASTContext.h"
|
173
|
15 #include "clang/AST/ComputeDependence.h"
|
|
16 #include "clang/AST/DependenceFlags.h"
|
150
|
17 #include "clang/AST/SelectorLocationsKind.h"
|
|
18 #include "clang/AST/Type.h"
|
|
19 #include "clang/AST/TypeLoc.h"
|
|
20 #include "llvm/ADT/SmallVector.h"
|
|
21 #include "llvm/Support/ErrorHandling.h"
|
|
22 #include <algorithm>
|
|
23 #include <cassert>
|
|
24 #include <cstdint>
|
|
25
|
|
26 using namespace clang;
|
|
27
|
|
28 ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,
|
|
29 ObjCMethodDecl *Method, SourceRange SR)
|
173
|
30 : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary),
|
150
|
31 NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {
|
|
32 Expr **SaveElements = getElements();
|
173
|
33 for (unsigned I = 0, N = Elements.size(); I != N; ++I)
|
|
34 SaveElements[I] = Elements[I];
|
150
|
35
|
173
|
36 setDependence(computeDependence(this));
|
150
|
37 }
|
|
38
|
|
39 ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
|
|
40 ArrayRef<Expr *> Elements,
|
|
41 QualType T, ObjCMethodDecl *Method,
|
|
42 SourceRange SR) {
|
|
43 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
|
|
44 return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
|
|
45 }
|
|
46
|
|
47 ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
|
|
48 unsigned NumElements) {
|
|
49 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
|
|
50 return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
|
|
51 }
|
|
52
|
|
53 ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
|
|
54 bool HasPackExpansions, QualType T,
|
|
55 ObjCMethodDecl *method,
|
|
56 SourceRange SR)
|
173
|
57 : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary),
|
150
|
58 NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
|
|
59 DictWithObjectsMethod(method) {
|
|
60 KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();
|
|
61 ExpansionData *Expansions =
|
|
62 HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr;
|
|
63 for (unsigned I = 0; I < NumElements; I++) {
|
|
64 KeyValues[I].Key = VK[I].Key;
|
|
65 KeyValues[I].Value = VK[I].Value;
|
|
66 if (Expansions) {
|
|
67 Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
|
|
68 if (VK[I].NumExpansions)
|
|
69 Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
|
|
70 else
|
|
71 Expansions[I].NumExpansionsPlusOne = 0;
|
|
72 }
|
|
73 }
|
173
|
74 setDependence(computeDependence(this));
|
150
|
75 }
|
|
76
|
|
77 ObjCDictionaryLiteral *
|
|
78 ObjCDictionaryLiteral::Create(const ASTContext &C,
|
|
79 ArrayRef<ObjCDictionaryElement> VK,
|
|
80 bool HasPackExpansions, QualType T,
|
|
81 ObjCMethodDecl *method, SourceRange SR) {
|
|
82 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
|
|
83 VK.size(), HasPackExpansions ? VK.size() : 0));
|
|
84 return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
|
|
85 }
|
|
86
|
|
87 ObjCDictionaryLiteral *
|
|
88 ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
|
|
89 bool HasPackExpansions) {
|
|
90 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
|
|
91 NumElements, HasPackExpansions ? NumElements : 0));
|
|
92 return new (Mem)
|
|
93 ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
|
|
94 }
|
|
95
|
|
96 QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {
|
|
97 if (isClassReceiver())
|
|
98 return ctx.getObjCInterfaceType(getClassReceiver());
|
|
99
|
|
100 if (isSuperReceiver())
|
|
101 return getSuperReceiverType();
|
|
102
|
|
103 return getBase()->getType();
|
|
104 }
|
|
105
|
|
106 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
|
|
107 SourceLocation LBracLoc,
|
|
108 SourceLocation SuperLoc, bool IsInstanceSuper,
|
|
109 QualType SuperType, Selector Sel,
|
|
110 ArrayRef<SourceLocation> SelLocs,
|
|
111 SelectorLocationsKind SelLocsK,
|
|
112 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
|
|
113 SourceLocation RBracLoc, bool isImplicit)
|
173
|
114 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
|
150
|
115 SelectorOrMethod(
|
|
116 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
|
|
117 Kind(IsInstanceSuper ? SuperInstance : SuperClass),
|
|
118 HasMethod(Method != nullptr), IsDelegateInitCall(false),
|
|
119 IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
|
|
120 RBracLoc(RBracLoc) {
|
|
121 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
|
|
122 setReceiverPointer(SuperType.getAsOpaquePtr());
|
173
|
123 setDependence(computeDependence(this));
|
150
|
124 }
|
|
125
|
|
126 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
|
|
127 SourceLocation LBracLoc,
|
|
128 TypeSourceInfo *Receiver, Selector Sel,
|
|
129 ArrayRef<SourceLocation> SelLocs,
|
|
130 SelectorLocationsKind SelLocsK,
|
|
131 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
|
|
132 SourceLocation RBracLoc, bool isImplicit)
|
173
|
133 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
|
150
|
134 SelectorOrMethod(
|
|
135 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
|
|
136 Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),
|
|
137 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
|
|
138 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
|
|
139 setReceiverPointer(Receiver);
|
173
|
140 setDependence(computeDependence(this));
|
150
|
141 }
|
|
142
|
|
143 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
|
|
144 SourceLocation LBracLoc, Expr *Receiver,
|
|
145 Selector Sel, ArrayRef<SourceLocation> SelLocs,
|
|
146 SelectorLocationsKind SelLocsK,
|
|
147 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
|
|
148 SourceLocation RBracLoc, bool isImplicit)
|
173
|
149 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
|
150
|
150 SelectorOrMethod(
|
|
151 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
|
|
152 Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),
|
|
153 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
|
|
154 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
|
|
155 setReceiverPointer(Receiver);
|
173
|
156 setDependence(computeDependence(this));
|
150
|
157 }
|
|
158
|
|
159 void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
|
|
160 ArrayRef<SourceLocation> SelLocs,
|
|
161 SelectorLocationsKind SelLocsK) {
|
|
162 setNumArgs(Args.size());
|
|
163 Expr **MyArgs = getArgs();
|
173
|
164 for (unsigned I = 0; I != Args.size(); ++I)
|
150
|
165 MyArgs[I] = Args[I];
|
|
166
|
|
167 SelLocsKind = SelLocsK;
|
|
168 if (!isImplicit()) {
|
|
169 if (SelLocsK == SelLoc_NonStandard)
|
|
170 std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
|
|
171 }
|
|
172 }
|
|
173
|
|
174 ObjCMessageExpr *
|
|
175 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
|
|
176 SourceLocation LBracLoc, SourceLocation SuperLoc,
|
|
177 bool IsInstanceSuper, QualType SuperType, Selector Sel,
|
|
178 ArrayRef<SourceLocation> SelLocs,
|
|
179 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
|
|
180 SourceLocation RBracLoc, bool isImplicit) {
|
|
181 assert((!SelLocs.empty() || isImplicit) &&
|
|
182 "No selector locs for non-implicit message");
|
|
183 ObjCMessageExpr *Mem;
|
|
184 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
|
|
185 if (isImplicit)
|
|
186 Mem = alloc(Context, Args.size(), 0);
|
|
187 else
|
|
188 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
|
|
189 return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
|
|
190 SuperType, Sel, SelLocs, SelLocsK, Method,
|
|
191 Args, RBracLoc, isImplicit);
|
|
192 }
|
|
193
|
|
194 ObjCMessageExpr *
|
|
195 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
|
|
196 SourceLocation LBracLoc, TypeSourceInfo *Receiver,
|
|
197 Selector Sel, ArrayRef<SourceLocation> SelLocs,
|
|
198 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
|
|
199 SourceLocation RBracLoc, bool isImplicit) {
|
|
200 assert((!SelLocs.empty() || isImplicit) &&
|
|
201 "No selector locs for non-implicit message");
|
|
202 ObjCMessageExpr *Mem;
|
|
203 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
|
|
204 if (isImplicit)
|
|
205 Mem = alloc(Context, Args.size(), 0);
|
|
206 else
|
|
207 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
|
|
208 return new (Mem)
|
|
209 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
|
|
210 Args, RBracLoc, isImplicit);
|
|
211 }
|
|
212
|
|
213 ObjCMessageExpr *
|
|
214 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
|
|
215 SourceLocation LBracLoc, Expr *Receiver, Selector Sel,
|
|
216 ArrayRef<SourceLocation> SelLocs,
|
|
217 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
|
|
218 SourceLocation RBracLoc, bool isImplicit) {
|
|
219 assert((!SelLocs.empty() || isImplicit) &&
|
|
220 "No selector locs for non-implicit message");
|
|
221 ObjCMessageExpr *Mem;
|
|
222 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
|
|
223 if (isImplicit)
|
|
224 Mem = alloc(Context, Args.size(), 0);
|
|
225 else
|
|
226 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
|
|
227 return new (Mem)
|
|
228 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
|
|
229 Args, RBracLoc, isImplicit);
|
|
230 }
|
|
231
|
|
232 ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
|
|
233 unsigned NumArgs,
|
|
234 unsigned NumStoredSelLocs) {
|
|
235 ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
|
|
236 return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
|
|
237 }
|
|
238
|
|
239 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
|
|
240 ArrayRef<Expr *> Args,
|
|
241 SourceLocation RBraceLoc,
|
|
242 ArrayRef<SourceLocation> SelLocs,
|
|
243 Selector Sel,
|
|
244 SelectorLocationsKind &SelLocsK) {
|
|
245 SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
|
|
246 unsigned NumStoredSelLocs =
|
|
247 (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
|
|
248 return alloc(C, Args.size(), NumStoredSelLocs);
|
|
249 }
|
|
250
|
|
251 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
|
|
252 unsigned NumStoredSelLocs) {
|
|
253 return (ObjCMessageExpr *)C.Allocate(
|
|
254 totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
|
|
255 alignof(ObjCMessageExpr));
|
|
256 }
|
|
257
|
|
258 void ObjCMessageExpr::getSelectorLocs(
|
|
259 SmallVectorImpl<SourceLocation> &SelLocs) const {
|
|
260 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
|
|
261 SelLocs.push_back(getSelectorLoc(i));
|
|
262 }
|
|
263
|
|
264
|
|
265 QualType ObjCMessageExpr::getCallReturnType(ASTContext &Ctx) const {
|
|
266 if (const ObjCMethodDecl *MD = getMethodDecl()) {
|
|
267 QualType QT = MD->getReturnType();
|
|
268 if (QT == Ctx.getObjCInstanceType()) {
|
|
269 // instancetype corresponds to expression types.
|
|
270 return getType();
|
|
271 }
|
|
272 return QT;
|
|
273 }
|
|
274
|
|
275 // Expression type might be different from an expected call return type,
|
|
276 // as expression type would never be a reference even if call returns a
|
|
277 // reference. Reconstruct the original expression type.
|
|
278 QualType QT = getType();
|
|
279 switch (getValueKind()) {
|
|
280 case VK_LValue:
|
|
281 return Ctx.getLValueReferenceType(QT);
|
|
282 case VK_XValue:
|
|
283 return Ctx.getRValueReferenceType(QT);
|
|
284 case VK_RValue:
|
|
285 return QT;
|
|
286 }
|
|
287 llvm_unreachable("Unsupported ExprValueKind");
|
|
288 }
|
|
289
|
|
290 SourceRange 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
|
|
306 Selector ObjCMessageExpr::getSelector() const {
|
|
307 if (HasMethod)
|
|
308 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
|
|
309 ->getSelector();
|
|
310 return Selector(SelectorOrMethod);
|
|
311 }
|
|
312
|
|
313 QualType 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
|
|
327 ObjCInterfaceDecl *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
|
|
339 Stmt::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
|
|
349 Stmt::const_child_range ObjCMessageExpr::children() const {
|
|
350 auto Children = const_cast<ObjCMessageExpr *>(this)->children();
|
|
351 return const_child_range(Children.begin(), Children.end());
|
|
352 }
|
|
353
|
|
354 StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
|
|
355 switch (getBridgeKind()) {
|
|
356 case OBC_Bridge:
|
|
357 return "__bridge";
|
|
358 case OBC_BridgeTransfer:
|
|
359 return "__bridge_transfer";
|
|
360 case OBC_BridgeRetained:
|
|
361 return "__bridge_retained";
|
|
362 }
|
|
363
|
|
364 llvm_unreachable("Invalid BridgeKind!");
|
|
365 }
|