xref: /llvm-project/clang/lib/AST/ExprObjC.cpp (revision dec6324cb05ac1d339c1b2bd43add968f2931c62)
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 
24 using namespace clang;
25 
26 ObjCArrayLiteral::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 
37 ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
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 
45 ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
46                                                 unsigned NumElements) {
47   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
48   return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
49 }
50 
51 ObjCDictionaryLiteral::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(this));
73 }
74 
75 ObjCDictionaryLiteral *
76 ObjCDictionaryLiteral::Create(const ASTContext &C,
77                               ArrayRef<ObjCDictionaryElement> VK,
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 
85 ObjCDictionaryLiteral *
86 ObjCDictionaryLiteral::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 
94 QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {
95   if (isClassReceiver())
96     return ctx.getObjCInterfaceType(getClassReceiver());
97 
98   if (isSuperReceiver())
99     return getSuperReceiverType();
100 
101   return getBase()->getType();
102 }
103 
104 ObjCMessageExpr::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(this));
122 }
123 
124 ObjCMessageExpr::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(this));
139 }
140 
141 ObjCMessageExpr::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(this));
155 }
156 
157 void 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(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
169   }
170 }
171 
172 ObjCMessageExpr *
173 ObjCMessageExpr::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(Context, Args.size(), 0);
185   else
186     Mem = alloc(Context, Args, 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 
192 ObjCMessageExpr *
193 ObjCMessageExpr::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(Context, Args.size(), 0);
204   else
205     Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
206   return new (Mem)
207       ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
208                       Args, RBracLoc, isImplicit);
209 }
210 
211 ObjCMessageExpr *
212 ObjCMessageExpr::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(Context, Args.size(), 0);
223   else
224     Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
225   return new (Mem)
226       ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
227                       Args, RBracLoc, isImplicit);
228 }
229 
230 ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
231                                               unsigned NumArgs,
232                                               unsigned NumStoredSelLocs) {
233   ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
234   return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
235 }
236 
237 ObjCMessageExpr *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, RBraceLoc);
244   unsigned NumStoredSelLocs =
245       (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
246   return alloc(C, Args.size(), NumStoredSelLocs);
247 }
248 
249 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
250                                         unsigned NumStoredSelLocs) {
251   return (ObjCMessageExpr *)C.Allocate(
252       totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
253       alignof(ObjCMessageExpr));
254 }
255 
256 void ObjCMessageExpr::getSelectorLocs(
257     SmallVectorImpl<SourceLocation> &SelLocs) const {
258   for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
259     SelLocs.push_back(getSelectorLoc(i));
260 }
261 
262 
263 QualType 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 
275 SourceRange 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 
291 Selector ObjCMessageExpr::getSelector() const {
292   if (HasMethod)
293     return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
294         ->getSelector();
295   return Selector(SelectorOrMethod);
296 }
297 
298 QualType 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 
312 ObjCInterfaceDecl *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 
324 Stmt::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 
334 Stmt::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 
339 StringRef 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