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"
15 #include "clang/AST/ComputeDependence.h"
16 #include "clang/AST/DependenceFlags.h"
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
ObjCArrayLiteral(ArrayRef<Expr * > Elements,QualType T,ObjCMethodDecl * Method,SourceRange SR)28 ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,
29 ObjCMethodDecl *Method, SourceRange SR)
30 : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary),
31 NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {
32 Expr **SaveElements = getElements();
33 for (unsigned I = 0, N = Elements.size(); I != N; ++I)
34 SaveElements[I] = Elements[I];
35
36 setDependence(computeDependence(this));
37 }
38
Create(const ASTContext & C,ArrayRef<Expr * > Elements,QualType T,ObjCMethodDecl * Method,SourceRange SR)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
CreateEmpty(const ASTContext & C,unsigned NumElements)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
ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,bool HasPackExpansions,QualType T,ObjCMethodDecl * method,SourceRange SR)53 ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
54 bool HasPackExpansions, QualType T,
55 ObjCMethodDecl *method,
56 SourceRange SR)
57 : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary),
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 }
74 setDependence(computeDependence(this));
75 }
76
77 ObjCDictionaryLiteral *
Create(const ASTContext & C,ArrayRef<ObjCDictionaryElement> VK,bool HasPackExpansions,QualType T,ObjCMethodDecl * method,SourceRange SR)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 *
CreateEmpty(const ASTContext & C,unsigned NumElements,bool HasPackExpansions)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
getReceiverType(const ASTContext & ctx) const96 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
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)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)
114 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
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());
123 setDependence(computeDependence(this));
124 }
125
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)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)
133 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
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);
140 setDependence(computeDependence(this));
141 }
142
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)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)
149 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
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);
156 setDependence(computeDependence(this));
157 }
158
initArgsAndSelLocs(ArrayRef<Expr * > Args,ArrayRef<SourceLocation> SelLocs,SelectorLocationsKind SelLocsK)159 void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
160 ArrayRef<SourceLocation> SelLocs,
161 SelectorLocationsKind SelLocsK) {
162 setNumArgs(Args.size());
163 Expr **MyArgs = getArgs();
164 for (unsigned I = 0; I != Args.size(); ++I)
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 *
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)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 *
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)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 *
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)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
CreateEmpty(const ASTContext & Context,unsigned NumArgs,unsigned NumStoredSelLocs)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
alloc(const ASTContext & C,ArrayRef<Expr * > Args,SourceLocation RBraceLoc,ArrayRef<SourceLocation> SelLocs,Selector Sel,SelectorLocationsKind & SelLocsK)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
alloc(const ASTContext & C,unsigned NumArgs,unsigned NumStoredSelLocs)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
getSelectorLocs(SmallVectorImpl<SourceLocation> & SelLocs) const258 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
getCallReturnType(ASTContext & Ctx) const265 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
getReceiverRange() const290 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
getSelector() const306 Selector ObjCMessageExpr::getSelector() const {
307 if (HasMethod)
308 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
309 ->getSelector();
310 return Selector(SelectorOrMethod);
311 }
312
getReceiverType() const313 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
getReceiverInterface() const327 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
children()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
children() const349 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
getBridgeKindName() const354 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 }
366