xref: /freebsd/contrib/llvm-project/clang/lib/AST/ExprObjC.cpp (revision 5ca8e32633c4ffbbcd6762e5888b6a4ba0708c6c)
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/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"
22 #include <algorithm>
23 #include <cassert>
24 #include <cstdint>
25 
26 using namespace clang;
27 
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];
35 
36   setDependence(computeDependence(this));
37 }
38 
39 ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
40                                            ArrayRef<Expr *> Elements,
41                                            QualType T, ObjCMethodDecl *Method,
42                                            SourceRange SR) {
43   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
44   return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
45 }
46 
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);
51 }
52 
53 ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
54                                              bool HasPackExpansions, QualType T,
55                                              ObjCMethodDecl *method,
56                                              SourceRange SR)
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;
66     if (Expansions) {
67       Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
68       if (VK[I].NumExpansions)
69         Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
70       else
71         Expansions[I].NumExpansionsPlusOne = 0;
72     }
73   }
74   setDependence(computeDependence(this));
75 }
76 
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);
85 }
86 
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));
92   return new (Mem)
93       ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
94 }
95 
96 QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {
97   if (isClassReceiver())
98     return ctx.getObjCInterfaceType(getClassReceiver());
99 
100   if (isSuperReceiver())
101     return getSuperReceiverType();
102 
103   return getBase()->getType();
104 }
105 
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),
115       SelectorOrMethod(
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),
120       RBracLoc(RBracLoc) {
121   initArgsAndSelLocs(Args, SelLocs, SelLocsK);
122   setReceiverPointer(SuperType.getAsOpaquePtr());
123   setDependence(computeDependence(this));
124 }
125 
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),
134       SelectorOrMethod(
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));
141 }
142 
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),
150       SelectorOrMethod(
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));
157 }
158 
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)
165     MyArgs[I] = Args[I];
166 
167   SelLocsKind = SelLocsK;
168   if (!isImplicit()) {
169     if (SelLocsK == SelLoc_NonStandard)
170       std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
171   }
172 }
173 
174 ObjCMessageExpr *
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();
185   if (isImplicit)
186     Mem = alloc(Context, Args.size(), 0);
187   else
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);
192 }
193 
194 ObjCMessageExpr *
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();
204   if (isImplicit)
205     Mem = alloc(Context, Args.size(), 0);
206   else
207     Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
208   return new (Mem)
209       ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
210                       Args, RBracLoc, isImplicit);
211 }
212 
213 ObjCMessageExpr *
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();
223   if (isImplicit)
224     Mem = alloc(Context, Args.size(), 0);
225   else
226     Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
227   return new (Mem)
228       ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
229                       Args, RBracLoc, isImplicit);
230 }
231 
232 ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
233                                               unsigned NumArgs,
234                                               unsigned NumStoredSelLocs) {
235   ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
236   return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
237 }
238 
239 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
240                                         ArrayRef<Expr *> Args,
241                                         SourceLocation RBraceLoc,
242                                         ArrayRef<SourceLocation> SelLocs,
243                                         Selector Sel,
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);
249 }
250 
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));
256 }
257 
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));
262 }
263 
264 
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.
270       return getType();
271     }
272     return QT;
273   }
274   return Ctx.getReferenceQualifiedType(this);
275 }
276 
277 SourceRange ObjCMessageExpr::getReceiverRange() const {
278   switch (getReceiverKind()) {
279   case Instance:
280     return getInstanceReceiver()->getSourceRange();
281 
282   case Class:
283     return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
284 
285   case SuperInstance:
286   case SuperClass:
287     return getSuperLoc();
288   }
289 
290   llvm_unreachable("Invalid ReceiverKind!");
291 }
292 
293 Selector ObjCMessageExpr::getSelector() const {
294   if (HasMethod)
295     return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
296         ->getSelector();
297   return Selector(SelectorOrMethod);
298 }
299 
300 QualType ObjCMessageExpr::getReceiverType() const {
301   switch (getReceiverKind()) {
302   case Instance:
303     return getInstanceReceiver()->getType();
304   case Class:
305     return getClassReceiver();
306   case SuperInstance:
307   case SuperClass:
308     return getSuperType();
309   }
310 
311   llvm_unreachable("unexpected receiver kind");
312 }
313 
314 ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
315   QualType T = getReceiverType();
316 
317   if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
318     return Ptr->getInterfaceDecl();
319 
320   if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
321     return Ty->getInterface();
322 
323   return nullptr;
324 }
325 
326 Stmt::child_range ObjCMessageExpr::children() {
327   Stmt **begin;
328   if (getReceiverKind() == Instance)
329     begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
330   else
331     begin = reinterpret_cast<Stmt **>(getArgs());
332   return child_range(begin,
333                      reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
334 }
335 
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());
339 }
340 
341 StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
342   switch (getBridgeKind()) {
343   case OBC_Bridge:
344     return "__bridge";
345   case OBC_BridgeTransfer:
346     return "__bridge_transfer";
347   case OBC_BridgeRetained:
348     return "__bridge_retained";
349   }
350 
351   llvm_unreachable("Invalid BridgeKind!");
352 }
353