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/SelectorLocationsKind.h"
16 #include "clang/AST/Type.h"
17 #include "clang/AST/TypeLoc.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include <algorithm>
21 #include <cassert>
22 #include <cstdint>
23
24 using namespace clang;
25
ObjCArrayLiteral(ArrayRef<Expr * > Elements,QualType T,ObjCMethodDecl * Method,SourceRange SR)26 ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,
27 ObjCMethodDecl *Method, SourceRange SR)
28 : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
29 false, false),
30 NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {
31 Expr **SaveElements = getElements();
32 for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
33 if (Elements[I]->isTypeDependent() || Elements[I]->isValueDependent())
34 ExprBits.ValueDependent = true;
35 if (Elements[I]->isInstantiationDependent())
36 ExprBits.InstantiationDependent = true;
37 if (Elements[I]->containsUnexpandedParameterPack())
38 ExprBits.ContainsUnexpandedParameterPack = true;
39
40 SaveElements[I] = Elements[I];
41 }
42 }
43
Create(const ASTContext & C,ArrayRef<Expr * > Elements,QualType T,ObjCMethodDecl * Method,SourceRange SR)44 ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
45 ArrayRef<Expr *> Elements,
46 QualType T, ObjCMethodDecl *Method,
47 SourceRange SR) {
48 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
49 return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
50 }
51
CreateEmpty(const ASTContext & C,unsigned NumElements)52 ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
53 unsigned NumElements) {
54 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
55 return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
56 }
57
ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,bool HasPackExpansions,QualType T,ObjCMethodDecl * method,SourceRange SR)58 ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
59 bool HasPackExpansions, QualType T,
60 ObjCMethodDecl *method,
61 SourceRange SR)
62 : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
63 false, false),
64 NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
65 DictWithObjectsMethod(method) {
66 KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();
67 ExpansionData *Expansions =
68 HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr;
69 for (unsigned I = 0; I < NumElements; I++) {
70 if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() ||
71 VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent())
72 ExprBits.ValueDependent = true;
73 if (VK[I].Key->isInstantiationDependent() ||
74 VK[I].Value->isInstantiationDependent())
75 ExprBits.InstantiationDependent = true;
76 if (VK[I].EllipsisLoc.isInvalid() &&
77 (VK[I].Key->containsUnexpandedParameterPack() ||
78 VK[I].Value->containsUnexpandedParameterPack()))
79 ExprBits.ContainsUnexpandedParameterPack = true;
80
81 KeyValues[I].Key = VK[I].Key;
82 KeyValues[I].Value = VK[I].Value;
83 if (Expansions) {
84 Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
85 if (VK[I].NumExpansions)
86 Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
87 else
88 Expansions[I].NumExpansionsPlusOne = 0;
89 }
90 }
91 }
92
93 ObjCDictionaryLiteral *
Create(const ASTContext & C,ArrayRef<ObjCDictionaryElement> VK,bool HasPackExpansions,QualType T,ObjCMethodDecl * method,SourceRange SR)94 ObjCDictionaryLiteral::Create(const ASTContext &C,
95 ArrayRef<ObjCDictionaryElement> VK,
96 bool HasPackExpansions, QualType T,
97 ObjCMethodDecl *method, SourceRange SR) {
98 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
99 VK.size(), HasPackExpansions ? VK.size() : 0));
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 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
107 NumElements, HasPackExpansions ? NumElements : 0));
108 return new (Mem)
109 ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
110 }
111
getReceiverType(const ASTContext & ctx) const112 QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {
113 if (isClassReceiver())
114 return ctx.getObjCInterfaceType(getClassReceiver());
115
116 if (isSuperReceiver())
117 return getSuperReceiverType();
118
119 return getBase()->getType();
120 }
121
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)122 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
123 SourceLocation LBracLoc,
124 SourceLocation SuperLoc, bool IsInstanceSuper,
125 QualType SuperType, Selector Sel,
126 ArrayRef<SourceLocation> SelLocs,
127 SelectorLocationsKind SelLocsK,
128 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
129 SourceLocation RBracLoc, bool isImplicit)
130 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
131 /*TypeDependent=*/false, /*ValueDependent=*/false,
132 /*InstantiationDependent=*/false,
133 /*ContainsUnexpandedParameterPack=*/false),
134 SelectorOrMethod(
135 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
136 Kind(IsInstanceSuper ? SuperInstance : SuperClass),
137 HasMethod(Method != nullptr), IsDelegateInitCall(false),
138 IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
139 RBracLoc(RBracLoc) {
140 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
141 setReceiverPointer(SuperType.getAsOpaquePtr());
142 }
143
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)144 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
145 SourceLocation LBracLoc,
146 TypeSourceInfo *Receiver, Selector Sel,
147 ArrayRef<SourceLocation> SelLocs,
148 SelectorLocationsKind SelLocsK,
149 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
150 SourceLocation RBracLoc, bool isImplicit)
151 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(),
152 T->isDependentType(), T->isInstantiationDependentType(),
153 T->containsUnexpandedParameterPack()),
154 SelectorOrMethod(
155 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
156 Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),
157 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
158 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
159 setReceiverPointer(Receiver);
160 }
161
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)162 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
163 SourceLocation LBracLoc, Expr *Receiver,
164 Selector Sel, ArrayRef<SourceLocation> SelLocs,
165 SelectorLocationsKind SelLocsK,
166 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
167 SourceLocation RBracLoc, bool isImplicit)
168 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
169 Receiver->isTypeDependent(), Receiver->isTypeDependent(),
170 Receiver->isInstantiationDependent(),
171 Receiver->containsUnexpandedParameterPack()),
172 SelectorOrMethod(
173 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
174 Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),
175 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
176 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
177 setReceiverPointer(Receiver);
178 }
179
initArgsAndSelLocs(ArrayRef<Expr * > Args,ArrayRef<SourceLocation> SelLocs,SelectorLocationsKind SelLocsK)180 void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
181 ArrayRef<SourceLocation> SelLocs,
182 SelectorLocationsKind SelLocsK) {
183 setNumArgs(Args.size());
184 Expr **MyArgs = getArgs();
185 for (unsigned I = 0; I != Args.size(); ++I) {
186 if (Args[I]->isTypeDependent())
187 ExprBits.TypeDependent = true;
188 if (Args[I]->isValueDependent())
189 ExprBits.ValueDependent = true;
190 if (Args[I]->isInstantiationDependent())
191 ExprBits.InstantiationDependent = true;
192 if (Args[I]->containsUnexpandedParameterPack())
193 ExprBits.ContainsUnexpandedParameterPack = true;
194
195 MyArgs[I] = Args[I];
196 }
197
198 SelLocsKind = SelLocsK;
199 if (!isImplicit()) {
200 if (SelLocsK == SelLoc_NonStandard)
201 std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
202 }
203 }
204
205 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)206 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
207 SourceLocation LBracLoc, SourceLocation SuperLoc,
208 bool IsInstanceSuper, QualType SuperType, Selector Sel,
209 ArrayRef<SourceLocation> SelLocs,
210 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
211 SourceLocation RBracLoc, bool isImplicit) {
212 assert((!SelLocs.empty() || isImplicit) &&
213 "No selector locs for non-implicit message");
214 ObjCMessageExpr *Mem;
215 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
216 if (isImplicit)
217 Mem = alloc(Context, Args.size(), 0);
218 else
219 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
220 return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
221 SuperType, Sel, SelLocs, SelLocsK, Method,
222 Args, RBracLoc, isImplicit);
223 }
224
225 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)226 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
227 SourceLocation LBracLoc, TypeSourceInfo *Receiver,
228 Selector Sel, ArrayRef<SourceLocation> SelLocs,
229 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
230 SourceLocation RBracLoc, bool isImplicit) {
231 assert((!SelLocs.empty() || isImplicit) &&
232 "No selector locs for non-implicit message");
233 ObjCMessageExpr *Mem;
234 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
235 if (isImplicit)
236 Mem = alloc(Context, Args.size(), 0);
237 else
238 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
239 return new (Mem)
240 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
241 Args, RBracLoc, isImplicit);
242 }
243
244 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)245 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
246 SourceLocation LBracLoc, Expr *Receiver, Selector Sel,
247 ArrayRef<SourceLocation> SelLocs,
248 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
249 SourceLocation RBracLoc, bool isImplicit) {
250 assert((!SelLocs.empty() || isImplicit) &&
251 "No selector locs for non-implicit message");
252 ObjCMessageExpr *Mem;
253 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
254 if (isImplicit)
255 Mem = alloc(Context, Args.size(), 0);
256 else
257 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
258 return new (Mem)
259 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
260 Args, RBracLoc, isImplicit);
261 }
262
CreateEmpty(const ASTContext & Context,unsigned NumArgs,unsigned NumStoredSelLocs)263 ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
264 unsigned NumArgs,
265 unsigned NumStoredSelLocs) {
266 ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
267 return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
268 }
269
alloc(const ASTContext & C,ArrayRef<Expr * > Args,SourceLocation RBraceLoc,ArrayRef<SourceLocation> SelLocs,Selector Sel,SelectorLocationsKind & SelLocsK)270 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
271 ArrayRef<Expr *> Args,
272 SourceLocation RBraceLoc,
273 ArrayRef<SourceLocation> SelLocs,
274 Selector Sel,
275 SelectorLocationsKind &SelLocsK) {
276 SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
277 unsigned NumStoredSelLocs =
278 (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
279 return alloc(C, Args.size(), NumStoredSelLocs);
280 }
281
alloc(const ASTContext & C,unsigned NumArgs,unsigned NumStoredSelLocs)282 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
283 unsigned NumStoredSelLocs) {
284 return (ObjCMessageExpr *)C.Allocate(
285 totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
286 alignof(ObjCMessageExpr));
287 }
288
getSelectorLocs(SmallVectorImpl<SourceLocation> & SelLocs) const289 void ObjCMessageExpr::getSelectorLocs(
290 SmallVectorImpl<SourceLocation> &SelLocs) const {
291 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
292 SelLocs.push_back(getSelectorLoc(i));
293 }
294
295
getCallReturnType(ASTContext & Ctx) const296 QualType ObjCMessageExpr::getCallReturnType(ASTContext &Ctx) const {
297 if (const ObjCMethodDecl *MD = getMethodDecl()) {
298 QualType QT = MD->getReturnType();
299 if (QT == Ctx.getObjCInstanceType()) {
300 // instancetype corresponds to expression types.
301 return getType();
302 }
303 return QT;
304 }
305
306 // Expression type might be different from an expected call return type,
307 // as expression type would never be a reference even if call returns a
308 // reference. Reconstruct the original expression type.
309 QualType QT = getType();
310 switch (getValueKind()) {
311 case VK_LValue:
312 return Ctx.getLValueReferenceType(QT);
313 case VK_XValue:
314 return Ctx.getRValueReferenceType(QT);
315 case VK_RValue:
316 return QT;
317 }
318 llvm_unreachable("Unsupported ExprValueKind");
319 }
320
getReceiverRange() const321 SourceRange ObjCMessageExpr::getReceiverRange() const {
322 switch (getReceiverKind()) {
323 case Instance:
324 return getInstanceReceiver()->getSourceRange();
325
326 case Class:
327 return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
328
329 case SuperInstance:
330 case SuperClass:
331 return getSuperLoc();
332 }
333
334 llvm_unreachable("Invalid ReceiverKind!");
335 }
336
getSelector() const337 Selector ObjCMessageExpr::getSelector() const {
338 if (HasMethod)
339 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
340 ->getSelector();
341 return Selector(SelectorOrMethod);
342 }
343
getReceiverType() const344 QualType ObjCMessageExpr::getReceiverType() const {
345 switch (getReceiverKind()) {
346 case Instance:
347 return getInstanceReceiver()->getType();
348 case Class:
349 return getClassReceiver();
350 case SuperInstance:
351 case SuperClass:
352 return getSuperType();
353 }
354
355 llvm_unreachable("unexpected receiver kind");
356 }
357
getReceiverInterface() const358 ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
359 QualType T = getReceiverType();
360
361 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
362 return Ptr->getInterfaceDecl();
363
364 if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
365 return Ty->getInterface();
366
367 return nullptr;
368 }
369
children()370 Stmt::child_range ObjCMessageExpr::children() {
371 Stmt **begin;
372 if (getReceiverKind() == Instance)
373 begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
374 else
375 begin = reinterpret_cast<Stmt **>(getArgs());
376 return child_range(begin,
377 reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
378 }
379
children() const380 Stmt::const_child_range ObjCMessageExpr::children() const {
381 auto Children = const_cast<ObjCMessageExpr *>(this)->children();
382 return const_child_range(Children.begin(), Children.end());
383 }
384
getBridgeKindName() const385 StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
386 switch (getBridgeKind()) {
387 case OBC_Bridge:
388 return "__bridge";
389 case OBC_BridgeTransfer:
390 return "__bridge_transfer";
391 case OBC_BridgeRetained:
392 return "__bridge_retained";
393 }
394
395 llvm_unreachable("Invalid BridgeKind!");
396 }
397