clang 22.0.0git
ExprObjC.cpp
Go to the documentation of this file.
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"
15#include "clang/AST/Attr.h"
18#include "clang/AST/Type.h"
19#include "clang/AST/TypeLoc.h"
20#include "llvm/Support/ErrorHandling.h"
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(this));
35}
36
38 ArrayRef<Expr *> Elements,
39 QualType T, ObjCMethodDecl *Method,
40 SourceRange SR) {
41 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
42 return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
43}
44
46 unsigned NumElements) {
47 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(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 }
73}
74
78 bool HasPackExpansions, QualType T,
79 ObjCMethodDecl *method, SourceRange SR) {
80 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
81 VK.size(), HasPackExpansions ? VK.size() : 0));
82 return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
83}
84
86ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
87 bool HasPackExpansions) {
88 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
89 NumElements, HasPackExpansions ? NumElements : 0));
90 return new (Mem)
91 ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
92}
93
95 if (isClassReceiver())
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,
109 SelectorLocationsKind SelLocsK,
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());
122}
123
124ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
125 SourceLocation LBracLoc,
126 TypeSourceInfo *Receiver, Selector Sel,
128 SelectorLocationsKind SelLocsK,
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);
139}
140
141ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
142 SourceLocation LBracLoc, Expr *Receiver,
144 SelectorLocationsKind SelLocsK,
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);
155}
156
157void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
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() && SelLocsK == SelLoc_NonStandard)
167 llvm::copy(SelLocs, getStoredSelLocs());
168}
169
172 SourceLocation LBracLoc, SourceLocation SuperLoc,
173 bool IsInstanceSuper, QualType SuperType, Selector Sel,
176 SourceLocation RBracLoc, bool isImplicit) {
177 assert((!SelLocs.empty() || isImplicit) &&
178 "No selector locs for non-implicit message");
179 ObjCMessageExpr *Mem;
181 if (isImplicit)
182 Mem = alloc(Context, Args.size(), 0);
183 else
184 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
185 return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
186 SuperType, Sel, SelLocs, SelLocsK, Method,
187 Args, RBracLoc, isImplicit);
188}
189
192 SourceLocation LBracLoc, TypeSourceInfo *Receiver,
195 SourceLocation RBracLoc, bool isImplicit) {
196 assert((!SelLocs.empty() || isImplicit) &&
197 "No selector locs for non-implicit message");
198 ObjCMessageExpr *Mem;
200 if (isImplicit)
201 Mem = alloc(Context, Args.size(), 0);
202 else
203 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
204 return new (Mem)
205 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
206 Args, RBracLoc, isImplicit);
207}
208
211 SourceLocation LBracLoc, Expr *Receiver, Selector Sel,
214 SourceLocation RBracLoc, bool isImplicit) {
215 assert((!SelLocs.empty() || isImplicit) &&
216 "No selector locs for non-implicit message");
217 ObjCMessageExpr *Mem;
219 if (isImplicit)
220 Mem = alloc(Context, Args.size(), 0);
221 else
222 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
223 return new (Mem)
224 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
225 Args, RBracLoc, isImplicit);
226}
227
229 unsigned NumArgs,
230 unsigned NumStoredSelLocs) {
231 ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
232 return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
233}
234
235ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
236 ArrayRef<Expr *> Args,
237 SourceLocation RBraceLoc,
239 Selector Sel,
240 SelectorLocationsKind &SelLocsK) {
241 SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
242 unsigned NumStoredSelLocs =
243 (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
244 return alloc(C, Args.size(), NumStoredSelLocs);
245}
246
247ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
248 unsigned NumStoredSelLocs) {
249 return (ObjCMessageExpr *)C.Allocate(
250 totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
251 alignof(ObjCMessageExpr));
252}
253
255 SmallVectorImpl<SourceLocation> &SelLocs) const {
256 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
257 SelLocs.push_back(getSelectorLoc(i));
258}
259
260
262 if (const ObjCMethodDecl *MD = getMethodDecl()) {
263 QualType QT = MD->getReturnType();
264 if (QT == Ctx.getObjCInstanceType()) {
265 // instancetype corresponds to expression types.
266 return getType();
267 }
268 return QT;
269 }
270 return Ctx.getReferenceQualifiedType(this);
271}
272
274 switch (getReceiverKind()) {
275 case Instance:
277
278 case Class:
280
281 case SuperInstance:
282 case SuperClass:
283 return getSuperLoc();
284 }
285
286 llvm_unreachable("Invalid ReceiverKind!");
287}
288
290 if (HasMethod)
291 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
292 ->getSelector();
293 return Selector(SelectorOrMethod);
294}
295
297 switch (getReceiverKind()) {
298 case Instance:
299 return getInstanceReceiver()->getType();
300 case Class:
301 return getClassReceiver();
302 case SuperInstance:
303 case SuperClass:
304 return getSuperType();
305 }
306
307 llvm_unreachable("unexpected receiver kind");
308}
309
312
314 return Ptr->getInterfaceDecl();
315
316 if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
317 return Ty->getInterface();
318
319 return nullptr;
320}
321
323 Stmt **begin;
324 if (getReceiverKind() == Instance)
325 begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
326 else
327 begin = reinterpret_cast<Stmt **>(getArgs());
328 return child_range(begin,
329 reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
330}
331
333 auto Children = const_cast<ObjCMessageExpr *>(this)->children();
334 return const_child_range(Children.begin(), Children.end());
335}
336
338 switch (getBridgeKind()) {
339 case OBC_Bridge:
340 return "__bridge";
342 return "__bridge_transfer";
344 return "__bridge_retained";
345 }
346
347 llvm_unreachable("Invalid BridgeKind!");
348}
Defines the clang::ASTContext interface.
SourceRange Range
Definition: SemaObjC.cpp:753
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
QualType getReferenceQualifiedType(const Expr *e) const
getReferenceQualifiedType - Given an expr, will return the type for that expression,...
QualType getObjCInstanceType()
Retrieve the Objective-C "instancetype" type.
Definition: ASTContext.h:2208
This represents one expression.
Definition: Expr.h:112
QualType getType() const
Definition: Expr.h:144
void setDependence(ExprDependence Deps)
Each concrete expr subclass is expected to compute its dependence and call this in the constructor.
Definition: Expr.h:137
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Definition: ExprObjC.h:192
static ObjCArrayLiteral * CreateEmpty(const ASTContext &C, unsigned NumElements)
Definition: ExprObjC.cpp:45
static ObjCArrayLiteral * Create(const ASTContext &C, ArrayRef< Expr * > Elements, QualType T, ObjCMethodDecl *Method, SourceRange SR)
Definition: ExprObjC.cpp:37
StringRef getBridgeKindName() const
Retrieve the kind of bridge being performed as a string.
Definition: ExprObjC.cpp:337
ObjCBridgeCastKind getBridgeKind() const
Determine which kind of bridge is being performed via this cast.
Definition: ExprObjC.h:1669
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition: ExprObjC.h:308
static ObjCDictionaryLiteral * Create(const ASTContext &C, ArrayRef< ObjCDictionaryElement > VK, bool HasPackExpansions, QualType T, ObjCMethodDecl *method, SourceRange SR)
Definition: ExprObjC.cpp:76
static ObjCDictionaryLiteral * CreateEmpty(const ASTContext &C, unsigned NumElements, bool HasPackExpansions)
Definition: ExprObjC.cpp:86
Represents an ObjC class declaration.
Definition: DeclObjC.h:1154
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:940
static 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)
Create a message send to super.
Definition: ExprObjC.cpp:171
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
Definition: ExprObjC.cpp:254
bool isImplicit() const
Indicates whether the message send was implicitly generated by the implementation.
Definition: ExprObjC.h:1225
static ObjCMessageExpr * CreateEmpty(const ASTContext &Context, unsigned NumArgs, unsigned NumStoredSelLocs)
Create an empty Objective-C message expression, to be filled in by subsequent calls.
Definition: ExprObjC.cpp:228
Expr ** getArgs()
Retrieve the arguments to this message, not including the receiver.
Definition: ExprObjC.h:1394
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Definition: ExprObjC.h:1268
QualType getCallReturnType(ASTContext &Ctx) const
Definition: ExprObjC.cpp:261
SourceLocation getSuperLoc() const
Retrieve the location of the 'super' keyword for a class or instance message to 'super',...
Definition: ExprObjC.h:1309
Selector getSelector() const
Definition: ExprObjC.cpp:289
@ SuperInstance
The receiver is the instance of the superclass object.
Definition: ExprObjC.h:954
@ Instance
The receiver is an object instance.
Definition: ExprObjC.h:948
@ SuperClass
The receiver is a superclass.
Definition: ExprObjC.h:951
@ Class
The receiver is a class.
Definition: ExprObjC.h:945
TypeSourceInfo * getClassReceiverTypeInfo() const
Returns a type-source information of a class message send, or nullptr if the message is not a class m...
Definition: ExprObjC.h:1296
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
Definition: ExprObjC.h:1287
ObjCInterfaceDecl * getReceiverInterface() const
Retrieve the Objective-C interface to which this message is being directed, if known.
Definition: ExprObjC.cpp:310
QualType getSuperType() const
Retrieve the type referred to by 'super'.
Definition: ExprObjC.h:1344
const ObjCMethodDecl * getMethodDecl() const
Definition: ExprObjC.h:1364
SourceRange getReceiverRange() const
Source range of the receiver.
Definition: ExprObjC.cpp:273
unsigned getNumSelectorLocs() const
Definition: ExprObjC.h:1444
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
Definition: ExprObjC.h:1229
child_range children()
Definition: ExprObjC.cpp:322
QualType getReceiverType() const
Retrieve the receiver type to which this message is being directed.
Definition: ExprObjC.cpp:296
SourceLocation getSelectorLoc(unsigned Index) const
Definition: ExprObjC.h:1433
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver.
Definition: ExprObjC.h:1390
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
Represents a pointer to an Objective C object.
Definition: TypeBase.h:7961
Represents a class type in Objective C.
Definition: TypeBase.h:7707
const Expr * getBase() const
Definition: ExprObjC.h:754
QualType getSuperReceiverType() const
Definition: ExprObjC.h:761
ObjCInterfaceDecl * getClassReceiver() const
Definition: ExprObjC.h:765
QualType getReceiverType(const ASTContext &ctx) const
Determine the type of the base, regardless of the kind of receiver.
Definition: ExprObjC.cpp:94
bool isClassReceiver() const
Definition: ExprObjC.h:771
bool isSuperReceiver() const
Definition: ExprObjC.h:770
A (possibly-)qualified type.
Definition: TypeBase.h:937
void * getAsOpaquePtr() const
Definition: TypeBase.h:984
Smart pointer class that efficiently represents Objective-C method names.
Encodes a location in the source.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
Definition: Stmt.h:85
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:334
llvm::iterator_range< child_iterator > child_range
Definition: Stmt.h:1561
llvm::iterator_range< const_child_iterator > const_child_range
Definition: Stmt.h:1562
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
Definition: TypeLoc.h:154
A container of type source information.
Definition: TypeBase.h:8314
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:272
const T * getAs() const
Member-template getAs<specific type>'.
Definition: TypeBase.h:9159
Definition: SPIR.cpp:47
The JSON file list parser is used to communicate input to InstallAPI.
SelectorLocationsKind
Whether all locations of the selector identifiers are in a "standard" position.
@ SelLoc_NonStandard
Non-standard.
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition: Specifiers.h:151
ExprDependence computeDependence(FullExpr *E)
SelectorLocationsKind hasStandardSelectorLocs(Selector Sel, ArrayRef< SourceLocation > SelLocs, ArrayRef< Expr * > Args, SourceLocation EndLoc)
Returns true if all SelLocs are in a "standard" location.
@ OBC_Bridge
Bridging via __bridge, which does nothing but reinterpret the bits.
@ OBC_BridgeTransfer
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC.
@ OBC_BridgeRetained
Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition: Specifiers.h:132
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:135
const FunctionProtoType * T
@ Class
The "class" keyword introduces the elaborated-type-specifier.
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
#define false
Definition: stdbool.h:26
A placeholder type used to construct an empty shell of a type, that will be filled in later (e....
Definition: Stmt.h:1412