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