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

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of clang/lib/AST/ExprObjC.cpp