Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/AST/ExprObjC.cpp
35259 views
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
28
ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,
29
ObjCMethodDecl *Method, SourceRange SR)
30
: Expr(ObjCArrayLiteralClass, T, VK_PRValue, 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
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)
57
: Expr(ObjCDictionaryLiteralClass, T, VK_PRValue, 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 *
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)
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
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
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
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 *
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
return Ctx.getReferenceQualifiedType(this);
275
}
276
277
SourceRange ObjCMessageExpr::getReceiverRange() const {
278
switch (getReceiverKind()) {
279
case Instance:
280
return getInstanceReceiver()->getSourceRange();
281
282
case Class:
283
return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
284
285
case SuperInstance:
286
case SuperClass:
287
return getSuperLoc();
288
}
289
290
llvm_unreachable("Invalid ReceiverKind!");
291
}
292
293
Selector ObjCMessageExpr::getSelector() const {
294
if (HasMethod)
295
return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
296
->getSelector();
297
return Selector(SelectorOrMethod);
298
}
299
300
QualType ObjCMessageExpr::getReceiverType() const {
301
switch (getReceiverKind()) {
302
case Instance:
303
return getInstanceReceiver()->getType();
304
case Class:
305
return getClassReceiver();
306
case SuperInstance:
307
case SuperClass:
308
return getSuperType();
309
}
310
311
llvm_unreachable("unexpected receiver kind");
312
}
313
314
ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
315
QualType T = getReceiverType();
316
317
if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
318
return Ptr->getInterfaceDecl();
319
320
if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
321
return Ty->getInterface();
322
323
return nullptr;
324
}
325
326
Stmt::child_range ObjCMessageExpr::children() {
327
Stmt **begin;
328
if (getReceiverKind() == Instance)
329
begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
330
else
331
begin = reinterpret_cast<Stmt **>(getArgs());
332
return child_range(begin,
333
reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
334
}
335
336
Stmt::const_child_range ObjCMessageExpr::children() const {
337
auto Children = const_cast<ObjCMessageExpr *>(this)->children();
338
return const_child_range(Children.begin(), Children.end());
339
}
340
341
StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
342
switch (getBridgeKind()) {
343
case OBC_Bridge:
344
return "__bridge";
345
case OBC_BridgeTransfer:
346
return "__bridge_transfer";
347
case OBC_BridgeRetained:
348
return "__bridge_retained";
349
}
350
351
llvm_unreachable("Invalid BridgeKind!");
352
}
353
354