/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/AST/StmtObjC.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- StmtObjC.h - Classes for representing ObjC statements --*- C++ -*-===// |
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 | | /// \file |
10 | | /// Defines the Objective-C statement AST node classes. |
11 | | |
12 | | #ifndef LLVM_CLANG_AST_STMTOBJC_H |
13 | | #define LLVM_CLANG_AST_STMTOBJC_H |
14 | | |
15 | | #include "clang/AST/Stmt.h" |
16 | | #include "llvm/Support/Compiler.h" |
17 | | |
18 | | namespace clang { |
19 | | |
20 | | /// Represents Objective-C's collection statement. |
21 | | /// |
22 | | /// This is represented as 'for (element 'in' collection-expression)' stmt. |
23 | | class ObjCForCollectionStmt : public Stmt { |
24 | | enum { ELEM, COLLECTION, BODY, END_EXPR }; |
25 | | Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt. |
26 | | SourceLocation ForLoc; |
27 | | SourceLocation RParenLoc; |
28 | | public: |
29 | | ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body, |
30 | | SourceLocation FCL, SourceLocation RPL); |
31 | | explicit ObjCForCollectionStmt(EmptyShell Empty) : |
32 | 0 | Stmt(ObjCForCollectionStmtClass, Empty) { } |
33 | | |
34 | 572 | Stmt *getElement() { return SubExprs[ELEM]; } |
35 | 410 | Expr *getCollection() { |
36 | 410 | return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); |
37 | 410 | } |
38 | 319 | Stmt *getBody() { return SubExprs[BODY]; } |
39 | | |
40 | 621 | const Stmt *getElement() const { return SubExprs[ELEM]; } |
41 | 1.10k | const Expr *getCollection() const { |
42 | 1.10k | return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); |
43 | 1.10k | } |
44 | 267 | const Stmt *getBody() const { return SubExprs[BODY]; } |
45 | | |
46 | 0 | void setElement(Stmt *S) { SubExprs[ELEM] = S; } |
47 | 0 | void setCollection(Expr *E) { |
48 | 0 | SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(E); |
49 | 0 | } |
50 | 284 | void setBody(Stmt *S) { SubExprs[BODY] = S; } |
51 | | |
52 | 19 | SourceLocation getForLoc() const { return ForLoc; } |
53 | 0 | void setForLoc(SourceLocation Loc) { ForLoc = Loc; } |
54 | 38 | SourceLocation getRParenLoc() const { return RParenLoc; } |
55 | 0 | void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } |
56 | | |
57 | 1.80k | SourceLocation getBeginLoc() const LLVM_READONLY { return ForLoc; } |
58 | 583 | SourceLocation getEndLoc() const LLVM_READONLY { |
59 | 583 | return SubExprs[BODY]->getEndLoc(); |
60 | 583 | } |
61 | | |
62 | 1.76M | static bool classof(const Stmt *T) { |
63 | 1.76M | return T->getStmtClass() == ObjCForCollectionStmtClass; |
64 | 1.76M | } |
65 | | |
66 | | // Iterators |
67 | 707 | child_range children() { |
68 | 707 | return child_range(&SubExprs[0], &SubExprs[END_EXPR]); |
69 | 707 | } |
70 | | |
71 | 0 | const_child_range children() const { |
72 | 0 | return const_child_range(&SubExprs[0], &SubExprs[END_EXPR]); |
73 | 0 | } |
74 | | }; |
75 | | |
76 | | /// Represents Objective-C's \@catch statement. |
77 | | class ObjCAtCatchStmt : public Stmt { |
78 | | private: |
79 | | VarDecl *ExceptionDecl; |
80 | | Stmt *Body; |
81 | | SourceLocation AtCatchLoc, RParenLoc; |
82 | | |
83 | | public: |
84 | | ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc, |
85 | | VarDecl *catchVarDecl, |
86 | | Stmt *atCatchStmt) |
87 | | : Stmt(ObjCAtCatchStmtClass), ExceptionDecl(catchVarDecl), |
88 | 335 | Body(atCatchStmt), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) { } |
89 | | |
90 | | explicit ObjCAtCatchStmt(EmptyShell Empty) : |
91 | 8 | Stmt(ObjCAtCatchStmtClass, Empty) { } |
92 | | |
93 | 258 | const Stmt *getCatchBody() const { return Body; } |
94 | 44 | Stmt *getCatchBody() { return Body; } |
95 | 8 | void setCatchBody(Stmt *S) { Body = S; } |
96 | | |
97 | 291 | const VarDecl *getCatchParamDecl() const { |
98 | 291 | return ExceptionDecl; |
99 | 291 | } |
100 | 44 | VarDecl *getCatchParamDecl() { |
101 | 44 | return ExceptionDecl; |
102 | 44 | } |
103 | 8 | void setCatchParamDecl(VarDecl *D) { ExceptionDecl = D; } |
104 | | |
105 | 24 | SourceLocation getAtCatchLoc() const { return AtCatchLoc; } |
106 | 8 | void setAtCatchLoc(SourceLocation Loc) { AtCatchLoc = Loc; } |
107 | 25 | SourceLocation getRParenLoc() const { return RParenLoc; } |
108 | 8 | void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } |
109 | | |
110 | 51 | SourceLocation getBeginLoc() const LLVM_READONLY { return AtCatchLoc; } |
111 | 39 | SourceLocation getEndLoc() const LLVM_READONLY { return Body->getEndLoc(); } |
112 | | |
113 | 8 | bool hasEllipsis() const { return getCatchParamDecl() == nullptr; } |
114 | | |
115 | 668 | static bool classof(const Stmt *T) { |
116 | 668 | return T->getStmtClass() == ObjCAtCatchStmtClass; |
117 | 668 | } |
118 | | |
119 | 40 | child_range children() { return child_range(&Body, &Body + 1); } |
120 | | |
121 | 0 | const_child_range children() const { |
122 | 0 | return const_child_range(&Body, &Body + 1); |
123 | 0 | } |
124 | | }; |
125 | | |
126 | | /// Represents Objective-C's \@finally statement |
127 | | class ObjCAtFinallyStmt : public Stmt { |
128 | | SourceLocation AtFinallyLoc; |
129 | | Stmt *AtFinallyStmt; |
130 | | |
131 | | public: |
132 | | ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt) |
133 | | : Stmt(ObjCAtFinallyStmtClass), AtFinallyLoc(atFinallyLoc), |
134 | 66 | AtFinallyStmt(atFinallyStmt) {} |
135 | | |
136 | | explicit ObjCAtFinallyStmt(EmptyShell Empty) : |
137 | 3 | Stmt(ObjCAtFinallyStmtClass, Empty) { } |
138 | | |
139 | 15 | const Stmt *getFinallyBody() const { return AtFinallyStmt; } |
140 | 23 | Stmt *getFinallyBody() { return AtFinallyStmt; } |
141 | 3 | void setFinallyBody(Stmt *S) { AtFinallyStmt = S; } |
142 | | |
143 | 41 | SourceLocation getBeginLoc() const LLVM_READONLY { return AtFinallyLoc; } |
144 | 43 | SourceLocation getEndLoc() const LLVM_READONLY { |
145 | 43 | return AtFinallyStmt->getEndLoc(); |
146 | 43 | } |
147 | | |
148 | 11 | SourceLocation getAtFinallyLoc() const { return AtFinallyLoc; } |
149 | 3 | void setAtFinallyLoc(SourceLocation Loc) { AtFinallyLoc = Loc; } |
150 | | |
151 | 439 | static bool classof(const Stmt *T) { |
152 | 439 | return T->getStmtClass() == ObjCAtFinallyStmtClass; |
153 | 439 | } |
154 | | |
155 | 64 | child_range children() { |
156 | 64 | return child_range(&AtFinallyStmt, &AtFinallyStmt+1); |
157 | 64 | } |
158 | | |
159 | 0 | const_child_range children() const { |
160 | 0 | return const_child_range(&AtFinallyStmt, &AtFinallyStmt + 1); |
161 | 0 | } |
162 | | }; |
163 | | |
164 | | /// Represents Objective-C's \@try ... \@catch ... \@finally statement. |
165 | | class ObjCAtTryStmt : public Stmt { |
166 | | private: |
167 | | // The location of the @ in the \@try. |
168 | | SourceLocation AtTryLoc; |
169 | | |
170 | | // The number of catch blocks in this statement. |
171 | | unsigned NumCatchStmts : 16; |
172 | | |
173 | | // Whether this statement has a \@finally statement. |
174 | | bool HasFinally : 1; |
175 | | |
176 | | /// Retrieve the statements that are stored after this \@try statement. |
177 | | /// |
178 | | /// The order of the statements in memory follows the order in the source, |
179 | | /// with the \@try body first, followed by the \@catch statements (if any) |
180 | | /// and, finally, the \@finally (if it exists). |
181 | 594 | Stmt **getStmts() { return reinterpret_cast<Stmt **> (this + 1); } |
182 | 536 | const Stmt* const *getStmts() const { |
183 | 536 | return reinterpret_cast<const Stmt * const*> (this + 1); |
184 | 536 | } |
185 | | |
186 | | ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, |
187 | | Stmt **CatchStmts, unsigned NumCatchStmts, |
188 | | Stmt *atFinallyStmt); |
189 | | |
190 | | explicit ObjCAtTryStmt(EmptyShell Empty, unsigned NumCatchStmts, |
191 | | bool HasFinally) |
192 | | : Stmt(ObjCAtTryStmtClass, Empty), NumCatchStmts(NumCatchStmts), |
193 | 3 | HasFinally(HasFinally) { } |
194 | | |
195 | | public: |
196 | | static ObjCAtTryStmt *Create(const ASTContext &Context, |
197 | | SourceLocation atTryLoc, Stmt *atTryStmt, |
198 | | Stmt **CatchStmts, unsigned NumCatchStmts, |
199 | | Stmt *atFinallyStmt); |
200 | | static ObjCAtTryStmt *CreateEmpty(const ASTContext &Context, |
201 | | unsigned NumCatchStmts, bool HasFinally); |
202 | | |
203 | | /// Retrieve the location of the @ in the \@try. |
204 | 30 | SourceLocation getAtTryLoc() const { return AtTryLoc; } |
205 | 3 | void setAtTryLoc(SourceLocation Loc) { AtTryLoc = Loc; } |
206 | | |
207 | | /// Retrieve the \@try body. |
208 | 219 | const Stmt *getTryBody() const { return getStmts()[0]; } |
209 | 47 | Stmt *getTryBody() { return getStmts()[0]; } |
210 | 3 | void setTryBody(Stmt *S) { getStmts()[0] = S; } |
211 | | |
212 | | /// Retrieve the number of \@catch statements in this try-catch-finally |
213 | | /// block. |
214 | 876 | unsigned getNumCatchStmts() const { return NumCatchStmts; } |
215 | | |
216 | | /// Retrieve a \@catch statement. |
217 | 269 | const ObjCAtCatchStmt *getCatchStmt(unsigned I) const { |
218 | 269 | assert(I < NumCatchStmts && "Out-of-bounds @catch index"); |
219 | 269 | return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]); |
220 | 269 | } |
221 | | |
222 | | /// Retrieve a \@catch statement. |
223 | 50 | ObjCAtCatchStmt *getCatchStmt(unsigned I) { |
224 | 50 | assert(I < NumCatchStmts && "Out-of-bounds @catch index"); |
225 | 50 | return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]); |
226 | 50 | } |
227 | | |
228 | | /// Set a particular catch statement. |
229 | 8 | void setCatchStmt(unsigned I, ObjCAtCatchStmt *S) { |
230 | 8 | assert(I < NumCatchStmts && "Out-of-bounds @catch index"); |
231 | 8 | getStmts()[I + 1] = S; |
232 | 8 | } |
233 | | |
234 | | /// Retrieve the \@finally statement, if any. |
235 | 463 | const ObjCAtFinallyStmt *getFinallyStmt() const { |
236 | 463 | if (!HasFinally) |
237 | 415 | return nullptr; |
238 | | |
239 | 48 | return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]); |
240 | 48 | } |
241 | 50 | ObjCAtFinallyStmt *getFinallyStmt() { |
242 | 50 | if (!HasFinally) |
243 | 19 | return nullptr; |
244 | | |
245 | 31 | return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]); |
246 | 31 | } |
247 | 3 | void setFinallyStmt(Stmt *S) { |
248 | 3 | assert(HasFinally && "@try does not have a @finally slot!"); |
249 | 3 | getStmts()[1 + NumCatchStmts] = S; |
250 | 3 | } |
251 | | |
252 | 81 | SourceLocation getBeginLoc() const LLVM_READONLY { return AtTryLoc; } |
253 | | SourceLocation getEndLoc() const LLVM_READONLY; |
254 | | |
255 | 7.61k | static bool classof(const Stmt *T) { |
256 | 7.61k | return T->getStmtClass() == ObjCAtTryStmtClass; |
257 | 7.61k | } |
258 | | |
259 | 76 | child_range children() { |
260 | 76 | return child_range(getStmts(), |
261 | 76 | getStmts() + 1 + NumCatchStmts + HasFinally); |
262 | 76 | } |
263 | | |
264 | 0 | const_child_range children() const { |
265 | 0 | return const_child_range(const_cast<ObjCAtTryStmt *>(this)->children()); |
266 | 0 | } |
267 | | }; |
268 | | |
269 | | /// Represents Objective-C's \@synchronized statement. |
270 | | /// |
271 | | /// Example: |
272 | | /// \code |
273 | | /// @synchronized (sem) { |
274 | | /// do-something; |
275 | | /// } |
276 | | /// \endcode |
277 | | class ObjCAtSynchronizedStmt : public Stmt { |
278 | | private: |
279 | | SourceLocation AtSynchronizedLoc; |
280 | | enum { SYNC_EXPR, SYNC_BODY, END_EXPR }; |
281 | | Stmt* SubStmts[END_EXPR]; |
282 | | |
283 | | public: |
284 | | ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr, |
285 | | Stmt *synchBody) |
286 | 48 | : Stmt(ObjCAtSynchronizedStmtClass) { |
287 | 48 | SubStmts[SYNC_EXPR] = synchExpr; |
288 | 48 | SubStmts[SYNC_BODY] = synchBody; |
289 | 48 | AtSynchronizedLoc = atSynchronizedLoc; |
290 | 48 | } |
291 | | explicit ObjCAtSynchronizedStmt(EmptyShell Empty) : |
292 | 0 | Stmt(ObjCAtSynchronizedStmtClass, Empty) { } |
293 | | |
294 | 8 | SourceLocation getAtSynchronizedLoc() const { return AtSynchronizedLoc; } |
295 | 0 | void setAtSynchronizedLoc(SourceLocation Loc) { AtSynchronizedLoc = Loc; } |
296 | | |
297 | 93 | const CompoundStmt *getSynchBody() const { |
298 | 93 | return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); |
299 | 93 | } |
300 | 103 | CompoundStmt *getSynchBody() { |
301 | 103 | return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); |
302 | 103 | } |
303 | 0 | void setSynchBody(Stmt *S) { SubStmts[SYNC_BODY] = S; } |
304 | | |
305 | 27 | const Expr *getSynchExpr() const { |
306 | 27 | return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); |
307 | 27 | } |
308 | 84 | Expr *getSynchExpr() { |
309 | 84 | return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); |
310 | 84 | } |
311 | 0 | void setSynchExpr(Stmt *S) { SubStmts[SYNC_EXPR] = S; } |
312 | | |
313 | 177 | SourceLocation getBeginLoc() const LLVM_READONLY { return AtSynchronizedLoc; } |
314 | 80 | SourceLocation getEndLoc() const LLVM_READONLY { |
315 | 80 | return getSynchBody()->getEndLoc(); |
316 | 80 | } |
317 | | |
318 | 4.47k | static bool classof(const Stmt *T) { |
319 | 4.47k | return T->getStmtClass() == ObjCAtSynchronizedStmtClass; |
320 | 4.47k | } |
321 | | |
322 | 152 | child_range children() { |
323 | 152 | return child_range(&SubStmts[0], &SubStmts[0]+END_EXPR); |
324 | 152 | } |
325 | | |
326 | 0 | const_child_range children() const { |
327 | 0 | return const_child_range(&SubStmts[0], &SubStmts[0] + END_EXPR); |
328 | 0 | } |
329 | | }; |
330 | | |
331 | | /// Represents Objective-C's \@throw statement. |
332 | | class ObjCAtThrowStmt : public Stmt { |
333 | | SourceLocation AtThrowLoc; |
334 | | Stmt *Throw; |
335 | | |
336 | | public: |
337 | | ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr) |
338 | 89 | : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) { |
339 | 89 | AtThrowLoc = atThrowLoc; |
340 | 89 | } |
341 | | explicit ObjCAtThrowStmt(EmptyShell Empty) : |
342 | 0 | Stmt(ObjCAtThrowStmtClass, Empty) { } |
343 | | |
344 | 51 | const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); } |
345 | 25 | Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); } |
346 | 0 | void setThrowExpr(Stmt *S) { Throw = S; } |
347 | | |
348 | 6 | SourceLocation getThrowLoc() const LLVM_READONLY { return AtThrowLoc; } |
349 | 0 | void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; } |
350 | | |
351 | 55 | SourceLocation getBeginLoc() const LLVM_READONLY { return AtThrowLoc; } |
352 | 16 | SourceLocation getEndLoc() const LLVM_READONLY { |
353 | 10 | return Throw ? Throw->getEndLoc() : AtThrowLoc6 ; |
354 | 16 | } |
355 | | |
356 | 4.62k | static bool classof(const Stmt *T) { |
357 | 4.62k | return T->getStmtClass() == ObjCAtThrowStmtClass; |
358 | 4.62k | } |
359 | | |
360 | 54 | child_range children() { return child_range(&Throw, &Throw+1); } |
361 | | |
362 | 0 | const_child_range children() const { |
363 | 0 | return const_child_range(&Throw, &Throw + 1); |
364 | 0 | } |
365 | | }; |
366 | | |
367 | | /// Represents Objective-C's \@autoreleasepool Statement |
368 | | class ObjCAutoreleasePoolStmt : public Stmt { |
369 | | SourceLocation AtLoc; |
370 | | Stmt *SubStmt; |
371 | | |
372 | | public: |
373 | | ObjCAutoreleasePoolStmt(SourceLocation atLoc, Stmt *subStmt) |
374 | 186 | : Stmt(ObjCAutoreleasePoolStmtClass), AtLoc(atLoc), SubStmt(subStmt) {} |
375 | | |
376 | | explicit ObjCAutoreleasePoolStmt(EmptyShell Empty) : |
377 | 0 | Stmt(ObjCAutoreleasePoolStmtClass, Empty) { } |
378 | | |
379 | 113 | const Stmt *getSubStmt() const { return SubStmt; } |
380 | 266 | Stmt *getSubStmt() { return SubStmt; } |
381 | 0 | void setSubStmt(Stmt *S) { SubStmt = S; } |
382 | | |
383 | 105 | SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; } |
384 | 11 | SourceLocation getEndLoc() const LLVM_READONLY { |
385 | 11 | return SubStmt->getEndLoc(); |
386 | 11 | } |
387 | | |
388 | 5 | SourceLocation getAtLoc() const { return AtLoc; } |
389 | 0 | void setAtLoc(SourceLocation Loc) { AtLoc = Loc; } |
390 | | |
391 | 2.74k | static bool classof(const Stmt *T) { |
392 | 2.74k | return T->getStmtClass() == ObjCAutoreleasePoolStmtClass; |
393 | 2.74k | } |
394 | | |
395 | 173 | child_range children() { return child_range(&SubStmt, &SubStmt + 1); } |
396 | | |
397 | 0 | const_child_range children() const { |
398 | 0 | return const_child_range(&SubStmt, &SubStmt + 1); |
399 | 0 | } |
400 | | }; |
401 | | |
402 | | } // end namespace clang |
403 | | |
404 | | #endif |