/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/AST/ExprObjC.cpp
Line | Count | Source (jump to first uncovered line) |
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 | 282 | NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) { |
32 | 282 | Expr **SaveElements = getElements(); |
33 | 746 | for (unsigned I = 0, N = Elements.size(); I != N; ++I464 ) |
34 | 464 | SaveElements[I] = Elements[I]; |
35 | | |
36 | 282 | setDependence(computeDependence(this)); |
37 | 282 | } |
38 | | |
39 | | ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C, |
40 | | ArrayRef<Expr *> Elements, |
41 | | QualType T, ObjCMethodDecl *Method, |
42 | 282 | SourceRange SR) { |
43 | 282 | void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Elements.size())); |
44 | 282 | return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR); |
45 | 282 | } |
46 | | |
47 | | ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C, |
48 | 4 | unsigned NumElements) { |
49 | 4 | void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements)); |
50 | 4 | return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements); |
51 | 4 | } |
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 | 210 | DictWithObjectsMethod(method) { |
60 | 210 | KeyValuePair *KeyValues = getTrailingObjects<KeyValuePair>(); |
61 | 210 | ExpansionData *Expansions = |
62 | 210 | HasPackExpansions ? getTrailingObjects<ExpansionData>()3 : nullptr207 ; |
63 | 531 | for (unsigned I = 0; I < NumElements; I++321 ) { |
64 | 321 | KeyValues[I].Key = VK[I].Key; |
65 | 321 | KeyValues[I].Value = VK[I].Value; |
66 | 321 | if (Expansions) { |
67 | 6 | Expansions[I].EllipsisLoc = VK[I].EllipsisLoc; |
68 | 6 | if (VK[I].NumExpansions) |
69 | 0 | Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1; |
70 | 6 | else |
71 | 6 | Expansions[I].NumExpansionsPlusOne = 0; |
72 | 6 | } |
73 | 321 | } |
74 | 210 | setDependence(computeDependence(this)); |
75 | 210 | } |
76 | | |
77 | | ObjCDictionaryLiteral * |
78 | | ObjCDictionaryLiteral::Create(const ASTContext &C, |
79 | | ArrayRef<ObjCDictionaryElement> VK, |
80 | | bool HasPackExpansions, QualType T, |
81 | 210 | ObjCMethodDecl *method, SourceRange SR) { |
82 | 210 | void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>( |
83 | 210 | VK.size(), HasPackExpansions ? VK.size()3 : 0207 )); |
84 | 210 | return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR); |
85 | 210 | } |
86 | | |
87 | | ObjCDictionaryLiteral * |
88 | | ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements, |
89 | 7 | bool HasPackExpansions) { |
90 | 7 | void *Mem = C.Allocate(totalSizeToAlloc<KeyValuePair, ExpansionData>( |
91 | 7 | NumElements, HasPackExpansions ? NumElements3 : 04 )); |
92 | 7 | return new (Mem) |
93 | 7 | ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions); |
94 | 7 | } |
95 | | |
96 | 3.65k | QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const { |
97 | 3.65k | if (isClassReceiver()) |
98 | 191 | return ctx.getObjCInterfaceType(getClassReceiver()); |
99 | | |
100 | 3.46k | if (isSuperReceiver()) |
101 | 121 | return getSuperReceiverType(); |
102 | | |
103 | 3.34k | return getBase()->getType(); |
104 | 3.46k | } |
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 | 1.24k | RBracLoc(RBracLoc) { |
121 | 1.24k | initArgsAndSelLocs(Args, SelLocs, SelLocsK); |
122 | 1.24k | setReceiverPointer(SuperType.getAsOpaquePtr()); |
123 | 1.24k | setDependence(computeDependence(this)); |
124 | 1.24k | } |
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 | 7.58k | IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) { |
138 | 7.58k | initArgsAndSelLocs(Args, SelLocs, SelLocsK); |
139 | 7.58k | setReceiverPointer(Receiver); |
140 | 7.58k | setDependence(computeDependence(this)); |
141 | 7.58k | } |
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 | 16.5k | IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) { |
154 | 16.5k | initArgsAndSelLocs(Args, SelLocs, SelLocsK); |
155 | 16.5k | setReceiverPointer(Receiver); |
156 | 16.5k | setDependence(computeDependence(this)); |
157 | 16.5k | } |
158 | | |
159 | | void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args, |
160 | | ArrayRef<SourceLocation> SelLocs, |
161 | 25.4k | SelectorLocationsKind SelLocsK) { |
162 | 25.4k | setNumArgs(Args.size()); |
163 | 25.4k | Expr **MyArgs = getArgs(); |
164 | 44.2k | for (unsigned I = 0; I != Args.size(); ++I18.8k ) |
165 | 18.8k | MyArgs[I] = Args[I]; |
166 | | |
167 | 25.4k | SelLocsKind = SelLocsK; |
168 | 25.4k | if (!isImplicit()) { |
169 | 22.5k | if (SelLocsK == SelLoc_NonStandard) |
170 | 1.54k | std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs()); |
171 | 22.5k | } |
172 | 25.4k | } |
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 | 1.24k | SourceLocation RBracLoc, bool isImplicit) { |
181 | 1.24k | assert((!SelLocs.empty() || isImplicit) && |
182 | 1.24k | "No selector locs for non-implicit message"); |
183 | 0 | ObjCMessageExpr *Mem; |
184 | 1.24k | SelectorLocationsKind SelLocsK = SelectorLocationsKind(); |
185 | 1.24k | if (isImplicit) |
186 | 74 | Mem = alloc(Context, Args.size(), 0); |
187 | 1.17k | else |
188 | 1.17k | Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); |
189 | 1.24k | return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper, |
190 | 1.24k | SuperType, Sel, SelLocs, SelLocsK, Method, |
191 | 1.24k | Args, RBracLoc, isImplicit); |
192 | 1.24k | } |
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 | 7.58k | SourceLocation RBracLoc, bool isImplicit) { |
200 | 7.58k | assert((!SelLocs.empty() || isImplicit) && |
201 | 7.58k | "No selector locs for non-implicit message"); |
202 | 0 | ObjCMessageExpr *Mem; |
203 | 7.58k | SelectorLocationsKind SelLocsK = SelectorLocationsKind(); |
204 | 7.58k | if (isImplicit) |
205 | 206 | Mem = alloc(Context, Args.size(), 0); |
206 | 7.37k | else |
207 | 7.37k | Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); |
208 | 7.58k | return new (Mem) |
209 | 7.58k | ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method, |
210 | 7.58k | Args, RBracLoc, isImplicit); |
211 | 7.58k | } |
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 | 16.5k | SourceLocation RBracLoc, bool isImplicit) { |
219 | 16.5k | assert((!SelLocs.empty() || isImplicit) && |
220 | 16.5k | "No selector locs for non-implicit message"); |
221 | 0 | ObjCMessageExpr *Mem; |
222 | 16.5k | SelectorLocationsKind SelLocsK = SelectorLocationsKind(); |
223 | 16.5k | if (isImplicit) |
224 | 2.53k | Mem = alloc(Context, Args.size(), 0); |
225 | 14.0k | else |
226 | 14.0k | Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); |
227 | 16.5k | return new (Mem) |
228 | 16.5k | ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method, |
229 | 16.5k | Args, RBracLoc, isImplicit); |
230 | 16.5k | } |
231 | | |
232 | | ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context, |
233 | | unsigned NumArgs, |
234 | 40 | unsigned NumStoredSelLocs) { |
235 | 40 | ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs); |
236 | 40 | return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs); |
237 | 40 | } |
238 | | |
239 | | ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, |
240 | | ArrayRef<Expr *> Args, |
241 | | SourceLocation RBraceLoc, |
242 | | ArrayRef<SourceLocation> SelLocs, |
243 | | Selector Sel, |
244 | 22.5k | SelectorLocationsKind &SelLocsK) { |
245 | 22.5k | SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc); |
246 | 22.5k | unsigned NumStoredSelLocs = |
247 | 22.5k | (SelLocsK == SelLoc_NonStandard) ? SelLocs.size()1.54k : 021.0k ; |
248 | 22.5k | return alloc(C, Args.size(), NumStoredSelLocs); |
249 | 22.5k | } |
250 | | |
251 | | ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs, |
252 | 25.4k | unsigned NumStoredSelLocs) { |
253 | 25.4k | return (ObjCMessageExpr *)C.Allocate( |
254 | 25.4k | totalSizeToAlloc<void *, SourceLocation>(NumArgs + 1, NumStoredSelLocs), |
255 | 25.4k | alignof(ObjCMessageExpr)); |
256 | 25.4k | } |
257 | | |
258 | | void ObjCMessageExpr::getSelectorLocs( |
259 | 661 | SmallVectorImpl<SourceLocation> &SelLocs) const { |
260 | 1.30k | for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i643 ) |
261 | 643 | SelLocs.push_back(getSelectorLoc(i)); |
262 | 661 | } |
263 | | |
264 | | |
265 | 9 | QualType ObjCMessageExpr::getCallReturnType(ASTContext &Ctx) const { |
266 | 9 | if (const ObjCMethodDecl *MD = getMethodDecl()) { |
267 | 9 | QualType QT = MD->getReturnType(); |
268 | 9 | if (QT == Ctx.getObjCInstanceType()) { |
269 | | // instancetype corresponds to expression types. |
270 | 0 | return getType(); |
271 | 0 | } |
272 | 9 | return QT; |
273 | 9 | } |
274 | 0 | return Ctx.getReferenceQualifiedType(this); |
275 | 9 | } |
276 | | |
277 | 72 | SourceRange ObjCMessageExpr::getReceiverRange() const { |
278 | 72 | switch (getReceiverKind()) { |
279 | 72 | case Instance: |
280 | 72 | return getInstanceReceiver()->getSourceRange(); |
281 | | |
282 | 0 | case Class: |
283 | 0 | return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange(); |
284 | | |
285 | 0 | case SuperInstance: |
286 | 0 | case SuperClass: |
287 | 0 | return getSuperLoc(); |
288 | 72 | } |
289 | | |
290 | 0 | llvm_unreachable("Invalid ReceiverKind!"); |
291 | 0 | } |
292 | | |
293 | 48.8k | Selector ObjCMessageExpr::getSelector() const { |
294 | 48.8k | if (HasMethod) |
295 | 48.0k | return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod) |
296 | 48.0k | ->getSelector(); |
297 | 840 | return Selector(SelectorOrMethod); |
298 | 48.8k | } |
299 | | |
300 | 92.2k | QualType ObjCMessageExpr::getReceiverType() const { |
301 | 92.2k | switch (getReceiverKind()) { |
302 | 80.3k | case Instance: |
303 | 80.3k | return getInstanceReceiver()->getType(); |
304 | 7.34k | case Class: |
305 | 7.34k | return getClassReceiver(); |
306 | 4.50k | case SuperInstance: |
307 | 4.54k | case SuperClass: |
308 | 4.54k | return getSuperType(); |
309 | 92.2k | } |
310 | | |
311 | 0 | llvm_unreachable("unexpected receiver kind"); |
312 | 0 | } |
313 | | |
314 | 91.9k | ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const { |
315 | 91.9k | QualType T = getReceiverType(); |
316 | | |
317 | 91.9k | if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>()) |
318 | 84.4k | return Ptr->getInterfaceDecl(); |
319 | | |
320 | 7.48k | if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>()) |
321 | 7.36k | return Ty->getInterface(); |
322 | | |
323 | 123 | return nullptr; |
324 | 7.48k | } |
325 | | |
326 | 94.4k | Stmt::child_range ObjCMessageExpr::children() { |
327 | 94.4k | Stmt **begin; |
328 | 94.4k | if (getReceiverKind() == Instance) |
329 | 63.4k | begin = reinterpret_cast<Stmt **>(getTrailingObjects<void *>()); |
330 | 30.9k | else |
331 | 30.9k | begin = reinterpret_cast<Stmt **>(getArgs()); |
332 | 94.4k | return child_range(begin, |
333 | 94.4k | reinterpret_cast<Stmt **>(getArgs() + getNumArgs())); |
334 | 94.4k | } |
335 | | |
336 | 0 | Stmt::const_child_range ObjCMessageExpr::children() const { |
337 | 0 | auto Children = const_cast<ObjCMessageExpr *>(this)->children(); |
338 | 0 | return const_child_range(Children.begin(), Children.end()); |
339 | 0 | } |
340 | | |
341 | 4 | StringRef ObjCBridgedCastExpr::getBridgeKindName() const { |
342 | 4 | switch (getBridgeKind()) { |
343 | 4 | case OBC_Bridge: |
344 | 4 | return "__bridge"; |
345 | 0 | case OBC_BridgeTransfer: |
346 | 0 | return "__bridge_transfer"; |
347 | 0 | case OBC_BridgeRetained: |
348 | 0 | return "__bridge_retained"; |
349 | 4 | } |
350 | | |
351 | 0 | llvm_unreachable("Invalid BridgeKind!"); |
352 | 0 | } |