1 //===--- ExprObjC.cpp - (ObjC) Expression AST Node Implementation ---------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the subclesses of Expr class declared in ExprObjC.h
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "clang/AST/ExprObjC.h"
15
16 #include "clang/AST/ASTContext.h"
17
18 using namespace clang;
19
ObjCArrayLiteral(ArrayRef<Expr * > Elements,QualType T,ObjCMethodDecl * Method,SourceRange SR)20 ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr *> Elements, QualType T,
21 ObjCMethodDecl *Method, SourceRange SR)
22 : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
23 false, false),
24 NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) {
25 Expr **SaveElements = getElements();
26 for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
27 if (Elements[I]->isTypeDependent() || Elements[I]->isValueDependent())
28 ExprBits.ValueDependent = true;
29 if (Elements[I]->isInstantiationDependent())
30 ExprBits.InstantiationDependent = true;
31 if (Elements[I]->containsUnexpandedParameterPack())
32 ExprBits.ContainsUnexpandedParameterPack = true;
33
34 SaveElements[I] = Elements[I];
35 }
36 }
37
Create(const ASTContext & C,ArrayRef<Expr * > Elements,QualType T,ObjCMethodDecl * Method,SourceRange SR)38 ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
39 ArrayRef<Expr *> Elements,
40 QualType T, ObjCMethodDecl *Method,
41 SourceRange SR) {
42 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size()));
43 return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR);
44 }
45
CreateEmpty(const ASTContext & C,unsigned NumElements)46 ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
47 unsigned NumElements) {
48
49 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
50 return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
51 }
52
ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,bool HasPackExpansions,QualType T,ObjCMethodDecl * method,SourceRange SR)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 if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() ||
66 VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent())
67 ExprBits.ValueDependent = true;
68 if (VK[I].Key->isInstantiationDependent() ||
69 VK[I].Value->isInstantiationDependent())
70 ExprBits.InstantiationDependent = true;
71 if (VK[I].EllipsisLoc.isInvalid() &&
72 (VK[I].Key->containsUnexpandedParameterPack() ||
73 VK[I].Value->containsUnexpandedParameterPack()))
74 ExprBits.ContainsUnexpandedParameterPack = true;
75
76 KeyValues[I].Key = VK[I].Key;
77 KeyValues[I].Value = VK[I].Value;
78 if (Expansions) {
79 Expansions[I].EllipsisLoc = VK[I].EllipsisLoc;
80 if (VK[I].NumExpansions)
81 Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1;
82 else
83 Expansions[I].NumExpansionsPlusOne = 0;
84 }
85 }
86 }
87
88 ObjCDictionaryLiteral *
Create(const ASTContext & C,ArrayRef<ObjCDictionaryElement> VK,bool HasPackExpansions,QualType T,ObjCMethodDecl * method,SourceRange SR)89 ObjCDictionaryLiteral::Create(const ASTContext &C,
90 ArrayRef<ObjCDictionaryElement> VK,
91 bool HasPackExpansions, QualType T,
92 ObjCMethodDecl *method, SourceRange SR) {
93 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
94 VK.size(), HasPackExpansions ? VK.size() : 0));
95 return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR);
96 }
97
98 ObjCDictionaryLiteral *
CreateEmpty(const ASTContext & C,unsigned NumElements,bool HasPackExpansions)99 ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements,
100 bool HasPackExpansions) {
101 void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>(
102 NumElements, HasPackExpansions ? NumElements : 0));
103 return new (Mem)
104 ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions);
105 }
106
getReceiverType(const ASTContext & ctx) const107 QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const {
108 if (isClassReceiver())
109 return ctx.getObjCInterfaceType(getClassReceiver());
110
111 if (isSuperReceiver())
112 return getSuperReceiverType();
113
114 return getBase()->getType();
115 }
116
ObjCMessageExpr(QualType T,ExprValueKind VK,SourceLocation LBracLoc,SourceLocation SuperLoc,bool IsInstanceSuper,QualType SuperType,Selector Sel,ArrayRef<SourceLocation> SelLocs,SelectorLocationsKind SelLocsK,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)117 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
118 SourceLocation LBracLoc,
119 SourceLocation SuperLoc, bool IsInstanceSuper,
120 QualType SuperType, Selector Sel,
121 ArrayRef<SourceLocation> SelLocs,
122 SelectorLocationsKind SelLocsK,
123 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
124 SourceLocation RBracLoc, bool isImplicit)
125 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
126 /*TypeDependent=*/false, /*ValueDependent=*/false,
127 /*InstantiationDependent=*/false,
128 /*ContainsUnexpandedParameterPack=*/false),
129 SelectorOrMethod(
130 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
131 Kind(IsInstanceSuper ? SuperInstance : SuperClass),
132 HasMethod(Method != nullptr), IsDelegateInitCall(false),
133 IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
134 RBracLoc(RBracLoc) {
135 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
136 setReceiverPointer(SuperType.getAsOpaquePtr());
137 }
138
ObjCMessageExpr(QualType T,ExprValueKind VK,SourceLocation LBracLoc,TypeSourceInfo * Receiver,Selector Sel,ArrayRef<SourceLocation> SelLocs,SelectorLocationsKind SelLocsK,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)139 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
140 SourceLocation LBracLoc,
141 TypeSourceInfo *Receiver, Selector Sel,
142 ArrayRef<SourceLocation> SelLocs,
143 SelectorLocationsKind SelLocsK,
144 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
145 SourceLocation RBracLoc, bool isImplicit)
146 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(),
147 T->isDependentType(), T->isInstantiationDependentType(),
148 T->containsUnexpandedParameterPack()),
149 SelectorOrMethod(
150 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
151 Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false),
152 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
153 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
154 setReceiverPointer(Receiver);
155 }
156
ObjCMessageExpr(QualType T,ExprValueKind VK,SourceLocation LBracLoc,Expr * Receiver,Selector Sel,ArrayRef<SourceLocation> SelLocs,SelectorLocationsKind SelLocsK,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)157 ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK,
158 SourceLocation LBracLoc, Expr *Receiver,
159 Selector Sel, ArrayRef<SourceLocation> SelLocs,
160 SelectorLocationsKind SelLocsK,
161 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
162 SourceLocation RBracLoc, bool isImplicit)
163 : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
164 Receiver->isTypeDependent(), Receiver->isTypeDependent(),
165 Receiver->isInstantiationDependent(),
166 Receiver->containsUnexpandedParameterPack()),
167 SelectorOrMethod(
168 reinterpret_cast<uintptr_t>(Method ? Method : Sel.getAsOpaquePtr())),
169 Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),
170 IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) {
171 initArgsAndSelLocs(Args, SelLocs, SelLocsK);
172 setReceiverPointer(Receiver);
173 }
174
initArgsAndSelLocs(ArrayRef<Expr * > Args,ArrayRef<SourceLocation> SelLocs,SelectorLocationsKind SelLocsK)175 void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args,
176 ArrayRef<SourceLocation> SelLocs,
177 SelectorLocationsKind SelLocsK) {
178 setNumArgs(Args.size());
179 Expr **MyArgs = getArgs();
180 for (unsigned I = 0; I != Args.size(); ++I) {
181 if (Args[I]->isTypeDependent())
182 ExprBits.TypeDependent = true;
183 if (Args[I]->isValueDependent())
184 ExprBits.ValueDependent = true;
185 if (Args[I]->isInstantiationDependent())
186 ExprBits.InstantiationDependent = true;
187 if (Args[I]->containsUnexpandedParameterPack())
188 ExprBits.ContainsUnexpandedParameterPack = true;
189
190 MyArgs[I] = Args[I];
191 }
192
193 SelLocsKind = SelLocsK;
194 if (!isImplicit()) {
195 if (SelLocsK == SelLoc_NonStandard)
196 std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
197 }
198 }
199
200 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)201 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
202 SourceLocation LBracLoc, SourceLocation SuperLoc,
203 bool IsInstanceSuper, QualType SuperType, Selector Sel,
204 ArrayRef<SourceLocation> SelLocs,
205 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
206 SourceLocation RBracLoc, bool isImplicit) {
207 assert((!SelLocs.empty() || isImplicit) &&
208 "No selector locs for non-implicit message");
209 ObjCMessageExpr *Mem;
210 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
211 if (isImplicit)
212 Mem = alloc(Context, Args.size(), 0);
213 else
214 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
215 return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
216 SuperType, Sel, SelLocs, SelLocsK, Method,
217 Args, RBracLoc, isImplicit);
218 }
219
220 ObjCMessageExpr *
Create(const ASTContext & Context,QualType T,ExprValueKind VK,SourceLocation LBracLoc,TypeSourceInfo * Receiver,Selector Sel,ArrayRef<SourceLocation> SelLocs,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)221 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
222 SourceLocation LBracLoc, TypeSourceInfo *Receiver,
223 Selector Sel, ArrayRef<SourceLocation> SelLocs,
224 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
225 SourceLocation RBracLoc, bool isImplicit) {
226 assert((!SelLocs.empty() || isImplicit) &&
227 "No selector locs for non-implicit message");
228 ObjCMessageExpr *Mem;
229 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
230 if (isImplicit)
231 Mem = alloc(Context, Args.size(), 0);
232 else
233 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
234 return new (Mem)
235 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
236 Args, RBracLoc, isImplicit);
237 }
238
239 ObjCMessageExpr *
Create(const ASTContext & Context,QualType T,ExprValueKind VK,SourceLocation LBracLoc,Expr * Receiver,Selector Sel,ArrayRef<SourceLocation> SelLocs,ObjCMethodDecl * Method,ArrayRef<Expr * > Args,SourceLocation RBracLoc,bool isImplicit)240 ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK,
241 SourceLocation LBracLoc, Expr *Receiver, Selector Sel,
242 ArrayRef<SourceLocation> SelLocs,
243 ObjCMethodDecl *Method, ArrayRef<Expr *> Args,
244 SourceLocation RBracLoc, bool isImplicit) {
245 assert((!SelLocs.empty() || isImplicit) &&
246 "No selector locs for non-implicit message");
247 ObjCMessageExpr *Mem;
248 SelectorLocationsKind SelLocsK = SelectorLocationsKind();
249 if (isImplicit)
250 Mem = alloc(Context, Args.size(), 0);
251 else
252 Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK);
253 return new (Mem)
254 ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method,
255 Args, RBracLoc, isImplicit);
256 }
257
CreateEmpty(const ASTContext & Context,unsigned NumArgs,unsigned NumStoredSelLocs)258 ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context,
259 unsigned NumArgs,
260 unsigned NumStoredSelLocs) {
261 ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs);
262 return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
263 }
264
alloc(const ASTContext & C,ArrayRef<Expr * > Args,SourceLocation RBraceLoc,ArrayRef<SourceLocation> SelLocs,Selector Sel,SelectorLocationsKind & SelLocsK)265 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C,
266 ArrayRef<Expr *> Args,
267 SourceLocation RBraceLoc,
268 ArrayRef<SourceLocation> SelLocs,
269 Selector Sel,
270 SelectorLocationsKind &SelLocsK) {
271 SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc);
272 unsigned NumStoredSelLocs =
273 (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0;
274 return alloc(C, Args.size(), NumStoredSelLocs);
275 }
276
alloc(const ASTContext & C,unsigned NumArgs,unsigned NumStoredSelLocs)277 ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs,
278 unsigned NumStoredSelLocs) {
279 return (ObjCMessageExpr *)C.Allocate(
280 totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs),
281 llvm::AlignOf<ObjCMessageExpr>::Alignment);
282 }
283
getSelectorLocs(SmallVectorImpl<SourceLocation> & SelLocs) const284 void ObjCMessageExpr::getSelectorLocs(
285 SmallVectorImpl<SourceLocation> &SelLocs) const {
286 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
287 SelLocs.push_back(getSelectorLoc(i));
288 }
289
getReceiverRange() const290 SourceRange ObjCMessageExpr::getReceiverRange() const {
291 switch (getReceiverKind()) {
292 case Instance:
293 return getInstanceReceiver()->getSourceRange();
294
295 case Class:
296 return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange();
297
298 case SuperInstance:
299 case SuperClass:
300 return getSuperLoc();
301 }
302
303 llvm_unreachable("Invalid ReceiverKind!");
304 }
305
getSelector() const306 Selector ObjCMessageExpr::getSelector() const {
307 if (HasMethod)
308 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
309 ->getSelector();
310 return Selector(SelectorOrMethod);
311 }
312
getReceiverType() const313 QualType ObjCMessageExpr::getReceiverType() const {
314 switch (getReceiverKind()) {
315 case Instance:
316 return getInstanceReceiver()->getType();
317 case Class:
318 return getClassReceiver();
319 case SuperInstance:
320 case SuperClass:
321 return getSuperType();
322 }
323
324 llvm_unreachable("unexpected receiver kind");
325 }
326
getReceiverInterface() const327 ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
328 QualType T = getReceiverType();
329
330 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
331 return Ptr->getInterfaceDecl();
332
333 if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
334 return Ty->getInterface();
335
336 return nullptr;
337 }
338
children()339 Stmt::child_range ObjCMessageExpr::children() {
340 Stmt **begin;
341 if (getReceiverKind() == Instance)
342 begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>());
343 else
344 begin = reinterpret_cast<Stmt **>(getArgs());
345 return child_range(begin,
346 reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
347 }
348
getBridgeKindName() const349 StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
350 switch (getBridgeKind()) {
351 case OBC_Bridge:
352 return "__bridge";
353 case OBC_BridgeTransfer:
354 return "__bridge_transfer";
355 case OBC_BridgeRetained:
356 return "__bridge_retained";
357 }
358
359 llvm_unreachable("Invalid BridgeKind!");
360 }
361