1 //===- ExprObjC.cpp - (ObjC) Expression AST Node Implementation -----------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements the subclesses of Expr class declared in ExprObjC.h
11 //===----------------------------------------------------------------------===//
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"
26 using namespace clang
;
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
];
36 setDependence(computeDependence(this));
39 ObjCArrayLiteral
*ObjCArrayLiteral::Create(const ASTContext
&C
,
40 ArrayRef
<Expr
*> Elements
,
41 QualType T
, ObjCMethodDecl
*Method
,
43 void *Mem
= C
.Allocate(totalSizeToAlloc
<Expr
*>(Elements
.size()));
44 return new (Mem
) ObjCArrayLiteral(Elements
, T
, Method
, SR
);
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
);
53 ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef
<ObjCDictionaryElement
> VK
,
54 bool HasPackExpansions
, QualType T
,
55 ObjCMethodDecl
*method
,
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
;
67 Expansions
[I
].EllipsisLoc
= VK
[I
].EllipsisLoc
;
68 if (VK
[I
].NumExpansions
)
69 Expansions
[I
].NumExpansionsPlusOne
= *VK
[I
].NumExpansions
+ 1;
71 Expansions
[I
].NumExpansionsPlusOne
= 0;
74 setDependence(computeDependence(this));
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
);
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));
93 ObjCDictionaryLiteral(EmptyShell(), NumElements
, HasPackExpansions
);
96 QualType
ObjCPropertyRefExpr::getReceiverType(const ASTContext
&ctx
) const {
97 if (isClassReceiver())
98 return ctx
.getObjCInterfaceType(getClassReceiver());
100 if (isSuperReceiver())
101 return getSuperReceiverType();
103 return getBase()->getType();
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
),
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
),
121 initArgsAndSelLocs(Args
, SelLocs
, SelLocsK
);
122 setReceiverPointer(SuperType
.getAsOpaquePtr());
123 setDependence(computeDependence(this));
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
),
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));
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
),
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));
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
)
167 SelLocsKind
= SelLocsK
;
169 if (SelLocsK
== SelLoc_NonStandard
)
170 std::copy(SelLocs
.begin(), SelLocs
.end(), getStoredSelLocs());
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();
186 Mem
= alloc(Context
, Args
.size(), 0);
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
);
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();
205 Mem
= alloc(Context
, Args
.size(), 0);
207 Mem
= alloc(Context
, Args
, RBracLoc
, SelLocs
, Sel
, SelLocsK
);
209 ObjCMessageExpr(T
, VK
, LBracLoc
, Receiver
, Sel
, SelLocs
, SelLocsK
, Method
,
210 Args
, RBracLoc
, 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();
224 Mem
= alloc(Context
, Args
.size(), 0);
226 Mem
= alloc(Context
, Args
, RBracLoc
, SelLocs
, Sel
, SelLocsK
);
228 ObjCMessageExpr(T
, VK
, LBracLoc
, Receiver
, Sel
, SelLocs
, SelLocsK
, Method
,
229 Args
, RBracLoc
, isImplicit
);
232 ObjCMessageExpr
*ObjCMessageExpr::CreateEmpty(const ASTContext
&Context
,
234 unsigned NumStoredSelLocs
) {
235 ObjCMessageExpr
*Mem
= alloc(Context
, NumArgs
, NumStoredSelLocs
);
236 return new (Mem
) ObjCMessageExpr(EmptyShell(), NumArgs
);
239 ObjCMessageExpr
*ObjCMessageExpr::alloc(const ASTContext
&C
,
240 ArrayRef
<Expr
*> Args
,
241 SourceLocation RBraceLoc
,
242 ArrayRef
<SourceLocation
> SelLocs
,
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
);
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
));
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
));
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.
274 return Ctx
.getReferenceQualifiedType(this);
277 SourceRange
ObjCMessageExpr::getReceiverRange() const {
278 switch (getReceiverKind()) {
280 return getInstanceReceiver()->getSourceRange();
283 return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
287 return getSuperLoc();
290 llvm_unreachable("Invalid ReceiverKind!");
293 Selector
ObjCMessageExpr::getSelector() const {
295 return reinterpret_cast<const ObjCMethodDecl
*>(SelectorOrMethod
)
297 return Selector(SelectorOrMethod
);
300 QualType
ObjCMessageExpr::getReceiverType() const {
301 switch (getReceiverKind()) {
303 return getInstanceReceiver()->getType();
305 return getClassReceiver();
308 return getSuperType();
311 llvm_unreachable("unexpected receiver kind");
314 ObjCInterfaceDecl
*ObjCMessageExpr::getReceiverInterface() const {
315 QualType T
= getReceiverType();
317 if (const ObjCObjectPointerType
*Ptr
= T
->getAs
<ObjCObjectPointerType
>())
318 return Ptr
->getInterfaceDecl();
320 if (const ObjCObjectType
*Ty
= T
->getAs
<ObjCObjectType
>())
321 return Ty
->getInterface();
326 Stmt::child_range
ObjCMessageExpr::children() {
328 if (getReceiverKind() == Instance
)
329 begin
= reinterpret_cast<Stmt
**>(getTrailingObjects
<void *>());
331 begin
= reinterpret_cast<Stmt
**>(getArgs());
332 return child_range(begin
,
333 reinterpret_cast<Stmt
**>(getArgs() + getNumArgs()));
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());
341 StringRef
ObjCBridgedCastExpr::getBridgeKindName() const {
342 switch (getBridgeKind()) {
345 case OBC_BridgeTransfer
:
346 return "__bridge_transfer";
347 case OBC_BridgeRetained
:
348 return "__bridge_retained";
351 llvm_unreachable("Invalid BridgeKind!");