clang 23.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,
28 bool ExpressibleAsConstantInitializer,
29 SourceRange SR)
30 : ObjCObjectLiteral(ObjCArrayLiteralClass, T,
31 ExpressibleAsConstantInitializer, VK_PRValue,
33 NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {
34 Expr **SaveElements = getElements();
35 for (unsigned I = 0, N = Elements.size(); I != N; ++I)
36 SaveElements[I] = Elements[I];
37
38 setDependence(computeDependence(this));
39}
40
44 bool ExpressibleAsConstantInitializer,
45 SourceRange SR) {
46 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
47 return new (Mem) ObjCArrayLiteral(Elements, T, Method,
48 ExpressibleAsConstantInitializer, SR);
49}
50
52 unsigned NumElements) {
53 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
54 auto *ALE = new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
55 ALE->setExpressibleAsConstantInitializer(NumElements == 0);
56 return ALE;
57}
58
59ObjCDictionaryLiteral::ObjCDictionaryLiteral(
60 ArrayRef<ObjCDictionaryElement> VK, bool HasPackExpansions, QualType T,
61 ObjCMethodDecl *Method, bool ExpressibleAsConstantInitializer,
62 SourceRange SR)
63 : ObjCObjectLiteral(ObjCDictionaryLiteralClass, T,
64 ExpressibleAsConstantInitializer, VK_PRValue,
66 NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
67 DictWithObjectsMethod(Method) {
68 KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();
69 ExpansionData *Expansions =
70 HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr;
71 for (unsigned I = 0; I < NumElements; I++) {
72 KeyValues[I].Key = VK[I].Key;
73 KeyValues[I].Value = VK[I].Value;
74 if (Expansions) {
75 Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
76 if (VK[I].NumExpansions)
77 Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
78 else
79 Expansions[I].NumExpansionsPlusOne = 0;
80 }
81 }
83}
84
85ObjCDictionaryLiteral *ObjCDictionaryLiteral::Create(
87 bool HasPackExpansions, QualType T, ObjCMethodDecl *Method,
88 bool ExpressibleAsConstantInitializer, SourceRange SR) {
89 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
90 VK.size(), HasPackExpansions ? VK.size() : 0));
91 return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, Method,
92 ExpressibleAsConstantInitializer, SR);
93}
94
96ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
97 bool HasPackExpansions) {
98 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
99 NumElements, HasPackExpansions ? NumElements : 0));
100 auto *DLE = new (Mem)
101 ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
102 DLE->setExpressibleAsConstantInitializer(NumElements == 0);
103 return DLE;
104}
105
107 if (isClassReceiver())
109
110 if (isSuperReceiver())
111 return getSuperReceiverType();
112
113 return getBase()->getType();
114}
115
116ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
117 SourceLocation LBracLoc,
118 SourceLocation SuperLoc, bool IsInstanceSuper,
119 QualType SuperType, Selector Sel,
121 SelectorLocationsKind SelLocsK,
123 SourceLocation RBracLoc, bool isImplicit)
124 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
125 SelectorOrMethod(
126 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
127 Kind(IsInstanceSuper ? SuperInstance : SuperClass),
128 HasMethod(Method != nullptr), IsDelegateInitCall(false),
129 IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
130 RBracLoc(RBracLoc) {
131 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
132 setReceiverPointer(SuperType.getAsOpaquePtr());
134}
135
136ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
137 SourceLocation LBracLoc,
138 TypeSourceInfo *Receiver, Selector Sel,
140 SelectorLocationsKind SelLocsK,
141 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
142 SourceLocation RBracLoc, bool isImplicit)
143 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
144 SelectorOrMethod(
145 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
146 Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),
147 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
148 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
149 setReceiverPointer(Receiver);
151}
152
153ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
154 SourceLocation LBracLoc, Expr *Receiver,
156 SelectorLocationsKind SelLocsK,
158 SourceLocation RBracLoc, bool isImplicit)
159 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
160 SelectorOrMethod(
161 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
162 Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),
163 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
164 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
165 setReceiverPointer(Receiver);
167}
168
169void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
171 SelectorLocationsKind SelLocsK) {
172 setNumArgs(Args.size());
173 Expr **MyArgs = getArgs();
174 for (unsigned I = 0; I != Args.size(); ++I)
175 MyArgs[I] = Args[I];
176
177 SelLocsKind = SelLocsK;
178 if (!isImplicit() && SelLocsK == SelLoc_NonStandard)
179 llvm::copy(SelLocs, getStoredSelLocs());
180}
181
184 SourceLocation LBracLoc, SourceLocation SuperLoc,
185 bool IsInstanceSuper, QualType SuperType, Selector Sel,
188 SourceLocation RBracLoc, bool isImplicit) {
189 assert((!SelLocs.empty() || isImplicit) &&
190 "No selector locs for non-implicit message");
191 ObjCMessageExpr *Mem;
193 if (isImplicit)
194 Mem = alloc(Context, Args.size(), 0);
195 else
196 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
197 return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
198 SuperType, Sel, SelLocs, SelLocsK, Method,
199 Args, RBracLoc, isImplicit);
200}
201
204 SourceLocation LBracLoc, TypeSourceInfo *Receiver,
207 SourceLocation RBracLoc, bool isImplicit) {
208 assert((!SelLocs.empty() || isImplicit) &&
209 "No selector locs for non-implicit message");
210 ObjCMessageExpr *Mem;
212 if (isImplicit)
213 Mem = alloc(Context, Args.size(), 0);
214 else
215 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
216 return new (Mem)
217 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
218 Args, RBracLoc, isImplicit);
219}
220
223 SourceLocation LBracLoc, Expr *Receiver, Selector Sel,
226 SourceLocation RBracLoc, bool isImplicit) {
227 assert((!SelLocs.empty() || isImplicit) &&
228 "No selector locs for non-implicit message");
229 ObjCMessageExpr *Mem;
231 if (isImplicit)
232 Mem = alloc(Context, Args.size(), 0);
233 else
234 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
235 return new (Mem)
236 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
237 Args, RBracLoc, isImplicit);
238}
239
240ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
241 unsigned NumArgs,
242 unsigned NumStoredSelLocs) {
243 ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
244 return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
245}
246
247ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
248 ArrayRef<Expr *> Args,
249 SourceLocation RBraceLoc,
251 Selector Sel,
252 SelectorLocationsKind &SelLocsK) {
253 SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
254 unsigned NumStoredSelLocs =
255 (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
256 return alloc(C, Args.size(), NumStoredSelLocs);
257}
258
259ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
260 unsigned NumStoredSelLocs) {
261 return (ObjCMessageExpr *)C.Allocate(
262 totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
263 alignof(ObjCMessageExpr));
264}
265
267 SmallVectorImpl<SourceLocation> &SelLocs) const {
268 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
269 SelLocs.push_back(getSelectorLoc(i));
270}
271
272
274 if (const ObjCMethodDecl *MD = getMethodDecl()) {
275 QualType QT = MD->getReturnType();
276 if (QT == Ctx.getObjCInstanceType()) {
277 // instancetype corresponds to expression types.
278 return getType();
279 }
280 return QT;
281 }
282 return Ctx.getReferenceQualifiedType(this);
283}
284
286 switch (getReceiverKind()) {
287 case Instance:
289
290 case Class:
292
293 case SuperInstance:
294 case SuperClass:
295 return getSuperLoc();
296 }
297
298 llvm_unreachable("Invalid ReceiverKind!");
299}
300
302 if (HasMethod)
303 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
304 ->getSelector();
305 return Selector(SelectorOrMethod);
306}
307
309 switch (getReceiverKind()) {
310 case Instance:
311 return getInstanceReceiver()->getType();
312 case Class:
313 return getClassReceiver();
314 case SuperInstance:
315 case SuperClass:
316 return getSuperType();
317 }
318
319 llvm_unreachable("unexpected receiver kind");
320}
321
324
326 return Ptr->getInterfaceDecl();
327
328 if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
329 return Ty->getInterface();
330
331 return nullptr;
332}
333
335 Stmt **begin;
336 if (getReceiverKind() == Instance)
337 begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
338 else
339 begin = reinterpret_cast<Stmt **>(getArgs());
340 return child_range(begin,
341 reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
342}
343
345 return const_cast<ObjCMessageExpr *>(this)->children();
346}
347
349 switch (getBridgeKind()) {
350 case OBC_Bridge:
351 return "__bridge";
353 return "__bridge_transfer";
355 return "__bridge_retained";
356 }
357
358 llvm_unreachable("Invalid BridgeKind!");
359}
Defines the clang::ASTContext interface.
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:226
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.
This represents one expression.
Definition Expr.h:112
Expr()=delete
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:220
static ObjCArrayLiteral * CreateEmpty(const ASTContext &C, unsigned NumElements)
Definition ExprObjC.cpp:51
static ObjCArrayLiteral * Create(const ASTContext &C, ArrayRef< Expr * > Elements, QualType T, ObjCMethodDecl *Method, bool ExpressibleAsConstantInitializer, SourceRange SR)
Definition ExprObjC.cpp:42
StringRef getBridgeKindName() const
Retrieve the kind of bridge being performed as a string.
Definition ExprObjC.cpp:348
ObjCBridgeCastKind getBridgeKind() const
Determine which kind of bridge is being performed via this cast.
Definition ExprObjC.h:1700
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition ExprObjC.h:342
static ObjCDictionaryLiteral * CreateEmpty(const ASTContext &C, unsigned NumElements, bool HasPackExpansions)
Definition ExprObjC.cpp:96
static ObjCDictionaryLiteral * Create(const ASTContext &C, ArrayRef< ObjCDictionaryElement > VK, bool HasPackExpansions, QualType T, ObjCMethodDecl *Method, bool ExpressibleAsConstantInitializer, SourceRange SR)
Definition ExprObjC.cpp:85
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:971
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:183
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
Definition ExprObjC.cpp:266
bool isImplicit() const
Indicates whether the message send was implicitly generated by the implementation.
Definition ExprObjC.h:1256
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:240
Expr ** getArgs()
Retrieve the arguments to this message, not including the receiver.
Definition ExprObjC.h:1425
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Definition ExprObjC.h:1299
QualType getCallReturnType(ASTContext &Ctx) const
Definition ExprObjC.cpp:273
SourceLocation getSuperLoc() const
Retrieve the location of the 'super' keyword for a class or instance message to 'super',...
Definition ExprObjC.h:1340
Selector getSelector() const
Definition ExprObjC.cpp:301
@ SuperInstance
The receiver is the instance of the superclass object.
Definition ExprObjC.h:985
@ Instance
The receiver is an object instance.
Definition ExprObjC.h:979
@ SuperClass
The receiver is a superclass.
Definition ExprObjC.h:982
@ Class
The receiver is a class.
Definition ExprObjC.h:976
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:1327
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
Definition ExprObjC.h:1318
ObjCInterfaceDecl * getReceiverInterface() const
Retrieve the Objective-C interface to which this message is being directed, if known.
Definition ExprObjC.cpp:322
QualType getSuperType() const
Retrieve the type referred to by 'super'.
Definition ExprObjC.h:1375
const ObjCMethodDecl * getMethodDecl() const
Definition ExprObjC.h:1395
SourceRange getReceiverRange() const
Source range of the receiver.
Definition ExprObjC.cpp:285
unsigned getNumSelectorLocs() const
Definition ExprObjC.h:1475
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
Definition ExprObjC.h:1260
child_range children()
Definition ExprObjC.cpp:334
QualType getReceiverType() const
Retrieve the receiver type to which this message is being directed.
Definition ExprObjC.cpp:308
SourceLocation getSelectorLoc(unsigned Index) const
Definition ExprObjC.h:1464
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver.
Definition ExprObjC.h:1421
ObjCMethodDecl - Represents an instance or class method declaration.
Definition DeclObjC.h:140
Base class for Objective-C object literals ("...", @42, @[],}).
Definition ExprObjC.h:51
Represents a pointer to an Objective C object.
Definition TypeBase.h:8049
const Expr * getBase() const
Definition ExprObjC.h:786
QualType getSuperReceiverType() const
Definition ExprObjC.h:793
ObjCInterfaceDecl * getClassReceiver() const
Definition ExprObjC.h:797
QualType getReceiverType(const ASTContext &ctx) const
Determine the type of the base, regardless of the kind of receiver.
Definition ExprObjC.cpp:106
bool isClassReceiver() const
Definition ExprObjC.h:803
bool isSuperReceiver() const
Definition ExprObjC.h:802
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:86
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
llvm::iterator_range< child_iterator > child_range
Definition Stmt.h:1583
llvm::iterator_range< const_child_iterator > const_child_range
Definition Stmt.h:1584
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
Definition TypeLoc.h:154
A container of type source information.
Definition TypeBase.h:8402
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition TypeLoc.h:267
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9261
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)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
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
__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:1434