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