1 //===--- StmtObjC.h - Classes for representing ObjC statements --*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the Objective-C statement AST node classes.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_STMTOBJC_H
15 #define LLVM_CLANG_AST_STMTOBJC_H
17 #include "clang/AST/Stmt.h"
21 /// ObjCForCollectionStmt - This represents Objective-c's collection statement;
22 /// represented as 'for (element 'in' collection-expression)' stmt.
24 class ObjCForCollectionStmt : public Stmt {
25 enum { ELEM, COLLECTION, BODY, END_EXPR };
26 Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt.
27 SourceLocation ForLoc;
28 SourceLocation RParenLoc;
30 ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body,
31 SourceLocation FCL, SourceLocation RPL);
32 explicit ObjCForCollectionStmt(EmptyShell Empty) :
33 Stmt(ObjCForCollectionStmtClass, Empty) { }
35 Stmt *getElement() { return SubExprs[ELEM]; }
36 Expr *getCollection() {
37 return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
39 Stmt *getBody() { return SubExprs[BODY]; }
41 const Stmt *getElement() const { return SubExprs[ELEM]; }
42 const Expr *getCollection() const {
43 return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
45 const Stmt *getBody() const { return SubExprs[BODY]; }
47 void setElement(Stmt *S) { SubExprs[ELEM] = S; }
48 void setCollection(Expr *E) {
49 SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(E);
51 void setBody(Stmt *S) { SubExprs[BODY] = S; }
53 SourceLocation getForLoc() const { return ForLoc; }
54 void setForLoc(SourceLocation Loc) { ForLoc = Loc; }
55 SourceLocation getRParenLoc() const { return RParenLoc; }
56 void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
58 SourceRange getSourceRange() const {
59 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
61 static bool classof(const Stmt *T) {
62 return T->getStmtClass() == ObjCForCollectionStmtClass;
64 static bool classof(const ObjCForCollectionStmt *) { return true; }
67 child_range children() {
68 return child_range(&SubExprs[0], &SubExprs[END_EXPR]);
72 /// ObjCAtCatchStmt - This represents objective-c's @catch statement.
73 class ObjCAtCatchStmt : public Stmt {
75 VarDecl *ExceptionDecl;
77 SourceLocation AtCatchLoc, RParenLoc;
80 ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
81 VarDecl *catchVarDecl,
83 : Stmt(ObjCAtCatchStmtClass), ExceptionDecl(catchVarDecl),
84 Body(atCatchStmt), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) { }
86 explicit ObjCAtCatchStmt(EmptyShell Empty) :
87 Stmt(ObjCAtCatchStmtClass, Empty) { }
89 const Stmt *getCatchBody() const { return Body; }
90 Stmt *getCatchBody() { return Body; }
91 void setCatchBody(Stmt *S) { Body = S; }
93 const VarDecl *getCatchParamDecl() const {
96 VarDecl *getCatchParamDecl() {
99 void setCatchParamDecl(VarDecl *D) { ExceptionDecl = D; }
101 SourceLocation getAtCatchLoc() const { return AtCatchLoc; }
102 void setAtCatchLoc(SourceLocation Loc) { AtCatchLoc = Loc; }
103 SourceLocation getRParenLoc() const { return RParenLoc; }
104 void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
106 SourceRange getSourceRange() const {
107 return SourceRange(AtCatchLoc, Body->getLocEnd());
110 bool hasEllipsis() const { return getCatchParamDecl() == 0; }
112 static bool classof(const Stmt *T) {
113 return T->getStmtClass() == ObjCAtCatchStmtClass;
115 static bool classof(const ObjCAtCatchStmt *) { return true; }
117 child_range children() { return child_range(&Body, &Body + 1); }
120 /// ObjCAtFinallyStmt - This represent objective-c's @finally Statement
121 class ObjCAtFinallyStmt : public Stmt {
123 SourceLocation AtFinallyLoc;
125 ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
126 : Stmt(ObjCAtFinallyStmtClass),
127 AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
129 explicit ObjCAtFinallyStmt(EmptyShell Empty) :
130 Stmt(ObjCAtFinallyStmtClass, Empty) { }
132 const Stmt *getFinallyBody() const { return AtFinallyStmt; }
133 Stmt *getFinallyBody() { return AtFinallyStmt; }
134 void setFinallyBody(Stmt *S) { AtFinallyStmt = S; }
136 SourceRange getSourceRange() const {
137 return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd());
140 SourceLocation getAtFinallyLoc() const { return AtFinallyLoc; }
141 void setAtFinallyLoc(SourceLocation Loc) { AtFinallyLoc = Loc; }
143 static bool classof(const Stmt *T) {
144 return T->getStmtClass() == ObjCAtFinallyStmtClass;
146 static bool classof(const ObjCAtFinallyStmt *) { return true; }
148 child_range children() {
149 return child_range(&AtFinallyStmt, &AtFinallyStmt+1);
153 /// ObjCAtTryStmt - This represent objective-c's over-all
154 /// @try ... @catch ... @finally statement.
155 class ObjCAtTryStmt : public Stmt {
157 // The location of the
158 SourceLocation AtTryLoc;
160 // The number of catch blocks in this statement.
161 unsigned NumCatchStmts : 16;
163 // Whether this statement has a @finally statement.
166 /// \brief Retrieve the statements that are stored after this @try statement.
168 /// The order of the statements in memory follows the order in the source,
169 /// with the @try body first, followed by the @catch statements (if any) and,
170 /// finally, the @finally (if it exists).
171 Stmt **getStmts() { return reinterpret_cast<Stmt **> (this + 1); }
172 const Stmt* const *getStmts() const {
173 return reinterpret_cast<const Stmt * const*> (this + 1);
176 ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
177 Stmt **CatchStmts, unsigned NumCatchStmts,
178 Stmt *atFinallyStmt);
180 explicit ObjCAtTryStmt(EmptyShell Empty, unsigned NumCatchStmts,
182 : Stmt(ObjCAtTryStmtClass, Empty), NumCatchStmts(NumCatchStmts),
183 HasFinally(HasFinally) { }
186 static ObjCAtTryStmt *Create(ASTContext &Context, SourceLocation atTryLoc,
188 Stmt **CatchStmts, unsigned NumCatchStmts,
189 Stmt *atFinallyStmt);
190 static ObjCAtTryStmt *CreateEmpty(ASTContext &Context,
191 unsigned NumCatchStmts,
194 /// \brief Retrieve the location of the @ in the @try.
195 SourceLocation getAtTryLoc() const { return AtTryLoc; }
196 void setAtTryLoc(SourceLocation Loc) { AtTryLoc = Loc; }
198 /// \brief Retrieve the @try body.
199 const Stmt *getTryBody() const { return getStmts()[0]; }
200 Stmt *getTryBody() { return getStmts()[0]; }
201 void setTryBody(Stmt *S) { getStmts()[0] = S; }
203 /// \brief Retrieve the number of @catch statements in this try-catch-finally
205 unsigned getNumCatchStmts() const { return NumCatchStmts; }
207 /// \brief Retrieve a @catch statement.
208 const ObjCAtCatchStmt *getCatchStmt(unsigned I) const {
209 assert(I < NumCatchStmts && "Out-of-bounds @catch index");
210 return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
213 /// \brief Retrieve a @catch statement.
214 ObjCAtCatchStmt *getCatchStmt(unsigned I) {
215 assert(I < NumCatchStmts && "Out-of-bounds @catch index");
216 return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
219 /// \brief Set a particular catch statement.
220 void setCatchStmt(unsigned I, ObjCAtCatchStmt *S) {
221 assert(I < NumCatchStmts && "Out-of-bounds @catch index");
222 getStmts()[I + 1] = S;
225 /// Retrieve the @finally statement, if any.
226 const ObjCAtFinallyStmt *getFinallyStmt() const {
230 return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
232 ObjCAtFinallyStmt *getFinallyStmt() {
236 return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
238 void setFinallyStmt(Stmt *S) {
239 assert(HasFinally && "@try does not have a @finally slot!");
240 getStmts()[1 + NumCatchStmts] = S;
243 SourceRange getSourceRange() const;
245 static bool classof(const Stmt *T) {
246 return T->getStmtClass() == ObjCAtTryStmtClass;
248 static bool classof(const ObjCAtTryStmt *) { return true; }
250 child_range children() {
251 return child_range(getStmts(),
252 getStmts() + 1 + NumCatchStmts + HasFinally);
256 /// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement.
257 /// Example: @synchronized (sem) {
261 class ObjCAtSynchronizedStmt : public Stmt {
263 enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
264 Stmt* SubStmts[END_EXPR];
265 SourceLocation AtSynchronizedLoc;
268 ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
270 : Stmt(ObjCAtSynchronizedStmtClass) {
271 SubStmts[SYNC_EXPR] = synchExpr;
272 SubStmts[SYNC_BODY] = synchBody;
273 AtSynchronizedLoc = atSynchronizedLoc;
275 explicit ObjCAtSynchronizedStmt(EmptyShell Empty) :
276 Stmt(ObjCAtSynchronizedStmtClass, Empty) { }
278 SourceLocation getAtSynchronizedLoc() const { return AtSynchronizedLoc; }
279 void setAtSynchronizedLoc(SourceLocation Loc) { AtSynchronizedLoc = Loc; }
281 const CompoundStmt *getSynchBody() const {
282 return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
284 CompoundStmt *getSynchBody() {
285 return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
287 void setSynchBody(Stmt *S) { SubStmts[SYNC_BODY] = S; }
289 const Expr *getSynchExpr() const {
290 return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
292 Expr *getSynchExpr() {
293 return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
295 void setSynchExpr(Stmt *S) { SubStmts[SYNC_EXPR] = S; }
297 SourceRange getSourceRange() const {
298 return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd());
301 static bool classof(const Stmt *T) {
302 return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
304 static bool classof(const ObjCAtSynchronizedStmt *) { return true; }
306 child_range children() {
307 return child_range(&SubStmts[0], &SubStmts[0]+END_EXPR);
311 /// ObjCAtThrowStmt - This represents objective-c's @throw statement.
312 class ObjCAtThrowStmt : public Stmt {
314 SourceLocation AtThrowLoc;
316 ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
317 : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) {
318 AtThrowLoc = atThrowLoc;
320 explicit ObjCAtThrowStmt(EmptyShell Empty) :
321 Stmt(ObjCAtThrowStmtClass, Empty) { }
323 const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
324 Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); }
325 void setThrowExpr(Stmt *S) { Throw = S; }
327 SourceLocation getThrowLoc() { return AtThrowLoc; }
328 void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; }
330 SourceRange getSourceRange() const {
332 return SourceRange(AtThrowLoc, Throw->getLocEnd());
334 return SourceRange(AtThrowLoc);
337 static bool classof(const Stmt *T) {
338 return T->getStmtClass() == ObjCAtThrowStmtClass;
340 static bool classof(const ObjCAtThrowStmt *) { return true; }
342 child_range children() { return child_range(&Throw, &Throw+1); }
345 /// ObjCAutoreleasePoolStmt - This represent objective-c's
346 /// @autoreleasepool Statement
347 class ObjCAutoreleasePoolStmt : public Stmt {
349 SourceLocation AtLoc;
351 ObjCAutoreleasePoolStmt(SourceLocation atLoc,
353 : Stmt(ObjCAutoreleasePoolStmtClass),
354 SubStmt(subStmt), AtLoc(atLoc) {}
356 explicit ObjCAutoreleasePoolStmt(EmptyShell Empty) :
357 Stmt(ObjCAutoreleasePoolStmtClass, Empty) { }
359 const Stmt *getSubStmt() const { return SubStmt; }
360 Stmt *getSubStmt() { return SubStmt; }
361 void setSubStmt(Stmt *S) { SubStmt = S; }
363 SourceRange getSourceRange() const {
364 return SourceRange(AtLoc, SubStmt->getLocEnd());
367 SourceLocation getAtLoc() const { return AtLoc; }
368 void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
370 static bool classof(const Stmt *T) {
371 return T->getStmtClass() == ObjCAutoreleasePoolStmtClass;
373 static bool classof(const ObjCAutoreleasePoolStmt *) { return true; }
375 child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
378 } // end namespace clang