xref: /freebsd/contrib/llvm-project/clang/lib/AST/ExprObjC.cpp (revision e64bea71c21eb42e97aa615188ba91f6cce0d36d)
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 <cassert>
21 #include <cstdint>
22 
23 using namespace clang;
24 
25 ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,
26                                    ObjCMethodDecl *Method, SourceRange SR)
27     : Expr(ObjCArrayLiteralClass, T, VK_PRValue, OK_Ordinary),
28       NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {
29   Expr **SaveElements = getElements();
30   for (unsigned I = 0, N = Elements.size(); I != N; ++I)
31     SaveElements[I] = Elements[I];
32 
33   setDependence(computeDependence(this));
34 }
35 
36 ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
37                                            ArrayRef<Expr *> Elements,
38                                            QualType T, ObjCMethodDecl *Method,
39                                            SourceRange SR) {
40   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
41   return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
42 }
43 
44 ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
45                                                 unsigned NumElements) {
46   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
47   return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
48 }
49 
50 ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
51                                              bool HasPackExpansions, QualType T,
52                                              ObjCMethodDecl *method,
53                                              SourceRange SR)
54     : Expr(ObjCDictionaryLiteralClass, T, VK_PRValue, OK_Ordinary),
55       NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR),
56       DictWithObjectsMethod(method) {
57   KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>();
58   ExpansionData *Expansions =
59       HasPackExpansions ? getTrailingObjects<ExpansionData>() : nullptr;
60   for (unsigned I = 0; I < NumElements; I++) {
61     KeyValues[I].Key = VK[I].Key;
62     KeyValues[I].Value = VK[I].Value;
63     if (Expansions) {
64       Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
65       if (VK[I].NumExpansions)
66         Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
67       else
68         Expansions[I].NumExpansionsPlusOne = 0;
69     }
70   }
71   setDependence(computeDependence(this));
72 }
73 
74 ObjCDictionaryLiteral *
75 ObjCDictionaryLiteral::Create(const ASTContext &C,
76                               ArrayRef<ObjCDictionaryElement> VK,
77                               bool HasPackExpansions, QualType T,
78                               ObjCMethodDecl *method, SourceRange SR) {
79   void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
80       VK.size(), HasPackExpansions ? VK.size() : 0));
81   return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
82 }
83 
84 ObjCDictionaryLiteral *
85 ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
86                                    bool HasPackExpansions) {
87   void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
88       NumElements, HasPackExpansions ? NumElements : 0));
89   return new (Mem)
90       ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
91 }
92 
93 QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {
94   if (isClassReceiver())
95     return ctx.getObjCInterfaceType(getClassReceiver());
96 
97   if (isSuperReceiver())
98     return getSuperReceiverType();
99 
100   return getBase()->getType();
101 }
102 
103 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
104                                  SourceLocation LBracLoc,
105                                  SourceLocation SuperLoc, bool IsInstanceSuper,
106                                  QualType SuperType, Selector Sel,
107                                  ArrayRef<SourceLocation> SelLocs,
108                                  SelectorLocationsKind SelLocsK,
109                                  ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
110                                  SourceLocation RBracLoc, bool isImplicit)
111     : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
112       SelectorOrMethod(
113           reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
114       Kind(IsInstanceSuper ? SuperInstance : SuperClass),
115       HasMethod(Method != nullptr), IsDelegateInitCall(false),
116       IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
117       RBracLoc(RBracLoc) {
118   initArgsAndSelLocs(Args, SelLocs, SelLocsK);
119   setReceiverPointer(SuperType.getAsOpaquePtr());
120   setDependence(computeDependence(this));
121 }
122 
123 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
124                                  SourceLocation LBracLoc,
125                                  TypeSourceInfo *Receiver, Selector Sel,
126                                  ArrayRef<SourceLocation> SelLocs,
127                                  SelectorLocationsKind SelLocsK,
128                                  ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
129                                  SourceLocation RBracLoc, bool isImplicit)
130     : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
131       SelectorOrMethod(
132           reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
133       Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),
134       IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
135   initArgsAndSelLocs(Args, SelLocs, SelLocsK);
136   setReceiverPointer(Receiver);
137   setDependence(computeDependence(this));
138 }
139 
140 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
141                                  SourceLocation LBracLoc, Expr *Receiver,
142                                  Selector Sel, ArrayRef<SourceLocation> SelLocs,
143                                  SelectorLocationsKind SelLocsK,
144                                  ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
145                                  SourceLocation RBracLoc, bool isImplicit)
146     : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary),
147       SelectorOrMethod(
148           reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
149       Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),
150       IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
151   initArgsAndSelLocs(Args, SelLocs, SelLocsK);
152   setReceiverPointer(Receiver);
153   setDependence(computeDependence(this));
154 }
155 
156 void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
157                                          ArrayRef<SourceLocation> SelLocs,
158                                          SelectorLocationsKind SelLocsK) {
159   setNumArgs(Args.size());
160   Expr **MyArgs = getArgs();
161   for (unsigned I = 0; I != Args.size(); ++I)
162     MyArgs[I] = Args[I];
163 
164   SelLocsKind = SelLocsK;
165   if (!isImplicit() && SelLocsK == SelLoc_NonStandard)
166     llvm::copy(SelLocs, getStoredSelLocs());
167 }
168 
169 ObjCMessageExpr *
170 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
171                         SourceLocation LBracLoc, SourceLocation SuperLoc,
172                         bool IsInstanceSuper, QualType SuperType, Selector Sel,
173                         ArrayRef<SourceLocation> SelLocs,
174                         ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
175                         SourceLocation RBracLoc, bool isImplicit) {
176   assert((!SelLocs.empty() || isImplicit) &&
177          "No selector locs for non-implicit message");
178   ObjCMessageExpr *Mem;
179   SelectorLocationsKind SelLocsK = SelectorLocationsKind();
180   if (isImplicit)
181     Mem = alloc(Context, Args.size(), 0);
182   else
183     Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
184   return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
185                                    SuperType, Sel, SelLocs, SelLocsK, Method,
186                                    Args, RBracLoc, isImplicit);
187 }
188 
189 ObjCMessageExpr *
190 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
191                         SourceLocation LBracLoc, TypeSourceInfo *Receiver,
192                         Selector Sel, ArrayRef<SourceLocation> SelLocs,
193                         ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
194                         SourceLocation RBracLoc, bool isImplicit) {
195   assert((!SelLocs.empty() || isImplicit) &&
196          "No selector locs for non-implicit message");
197   ObjCMessageExpr *Mem;
198   SelectorLocationsKind SelLocsK = SelectorLocationsKind();
199   if (isImplicit)
200     Mem = alloc(Context, Args.size(), 0);
201   else
202     Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
203   return new (Mem)
204       ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
205                       Args, RBracLoc, isImplicit);
206 }
207 
208 ObjCMessageExpr *
209 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
210                         SourceLocation LBracLoc, Expr *Receiver, Selector Sel,
211                         ArrayRef<SourceLocation> SelLocs,
212                         ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
213                         SourceLocation RBracLoc, bool isImplicit) {
214   assert((!SelLocs.empty() || isImplicit) &&
215          "No selector locs for non-implicit message");
216   ObjCMessageExpr *Mem;
217   SelectorLocationsKind SelLocsK = SelectorLocationsKind();
218   if (isImplicit)
219     Mem = alloc(Context, Args.size(), 0);
220   else
221     Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
222   return new (Mem)
223       ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
224                       Args, RBracLoc, isImplicit);
225 }
226 
227 ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
228                                               unsigned NumArgs,
229                                               unsigned NumStoredSelLocs) {
230   ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
231   return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
232 }
233 
234 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
235                                         ArrayRef<Expr *> Args,
236                                         SourceLocation RBraceLoc,
237                                         ArrayRef<SourceLocation> SelLocs,
238                                         Selector Sel,
239                                         SelectorLocationsKind &SelLocsK) {
240   SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
241   unsigned NumStoredSelLocs =
242       (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
243   return alloc(C, Args.size(), NumStoredSelLocs);
244 }
245 
246 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
247                                         unsigned NumStoredSelLocs) {
248   return (ObjCMessageExpr *)C.Allocate(
249       totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
250       alignof(ObjCMessageExpr));
251 }
252 
253 void ObjCMessageExpr::getSelectorLocs(
254     SmallVectorImpl<SourceLocation> &SelLocs) const {
255   for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
256     SelLocs.push_back(getSelectorLoc(i));
257 }
258 
259 
260 QualType ObjCMessageExpr::getCallReturnType(ASTContext &Ctx) const {
261   if (const ObjCMethodDecl *MD = getMethodDecl()) {
262     QualType QT = MD->getReturnType();
263     if (QT == Ctx.getObjCInstanceType()) {
264       // instancetype corresponds to expression types.
265       return getType();
266     }
267     return QT;
268   }
269   return Ctx.getReferenceQualifiedType(this);
270 }
271 
272 SourceRange ObjCMessageExpr::getReceiverRange() const {
273   switch (getReceiverKind()) {
274   case Instance:
275     return getInstanceReceiver()->getSourceRange();
276 
277   case Class:
278     return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
279 
280   case SuperInstance:
281   case SuperClass:
282     return getSuperLoc();
283   }
284 
285   llvm_unreachable("Invalid ReceiverKind!");
286 }
287 
288 Selector ObjCMessageExpr::getSelector() const {
289   if (HasMethod)
290     return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
291         ->getSelector();
292   return Selector(SelectorOrMethod);
293 }
294 
295 QualType ObjCMessageExpr::getReceiverType() const {
296   switch (getReceiverKind()) {
297   case Instance:
298     return getInstanceReceiver()->getType();
299   case Class:
300     return getClassReceiver();
301   case SuperInstance:
302   case SuperClass:
303     return getSuperType();
304   }
305 
306   llvm_unreachable("unexpected receiver kind");
307 }
308 
309 ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
310   QualType T = getReceiverType();
311 
312   if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
313     return Ptr->getInterfaceDecl();
314 
315   if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
316     return Ty->getInterface();
317 
318   return nullptr;
319 }
320 
321 Stmt::child_range ObjCMessageExpr::children() {
322   Stmt **begin;
323   if (getReceiverKind() == Instance)
324     begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
325   else
326     begin = reinterpret_cast<Stmt **>(getArgs());
327   return child_range(begin,
328                      reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
329 }
330 
331 Stmt::const_child_range ObjCMessageExpr::children() const {
332   auto Children = const_cast<ObjCMessageExpr *>(this)->children();
333   return const_child_range(Children.begin(), Children.end());
334 }
335 
336 StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
337   switch (getBridgeKind()) {
338   case OBC_Bridge:
339     return "__bridge";
340   case OBC_BridgeTransfer:
341     return "__bridge_transfer";
342   case OBC_BridgeRetained:
343     return "__bridge_retained";
344   }
345 
346   llvm_unreachable("Invalid BridgeKind!");
347 }
348