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