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 virtual 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 virtual child_iterator
child_begin();
68 virtual child_iterator
child_end();
71 /// ObjCAtCatchStmt - This represents objective-c's @catch statement.
72 class ObjCAtCatchStmt
: public Stmt
{
74 VarDecl
*ExceptionDecl
;
76 SourceLocation AtCatchLoc
, RParenLoc
;
79 ObjCAtCatchStmt(SourceLocation atCatchLoc
, SourceLocation rparenloc
,
80 VarDecl
*catchVarDecl
,
82 : Stmt(ObjCAtCatchStmtClass
), ExceptionDecl(catchVarDecl
),
83 Body(atCatchStmt
), AtCatchLoc(atCatchLoc
), RParenLoc(rparenloc
) { }
85 explicit ObjCAtCatchStmt(EmptyShell Empty
) :
86 Stmt(ObjCAtCatchStmtClass
, Empty
) { }
88 const Stmt
*getCatchBody() const { return Body
; }
89 Stmt
*getCatchBody() { return Body
; }
90 void setCatchBody(Stmt
*S
) { Body
= S
; }
92 const VarDecl
*getCatchParamDecl() const {
95 VarDecl
*getCatchParamDecl() {
98 void setCatchParamDecl(VarDecl
*D
) { ExceptionDecl
= D
; }
100 SourceLocation
getAtCatchLoc() const { return AtCatchLoc
; }
101 void setAtCatchLoc(SourceLocation Loc
) { AtCatchLoc
= Loc
; }
102 SourceLocation
getRParenLoc() const { return RParenLoc
; }
103 void setRParenLoc(SourceLocation Loc
) { RParenLoc
= Loc
; }
105 virtual SourceRange
getSourceRange() const {
106 return SourceRange(AtCatchLoc
, Body
->getLocEnd());
109 bool hasEllipsis() const { return getCatchParamDecl() == 0; }
111 static bool classof(const Stmt
*T
) {
112 return T
->getStmtClass() == ObjCAtCatchStmtClass
;
114 static bool classof(const ObjCAtCatchStmt
*) { return true; }
116 virtual child_iterator
child_begin();
117 virtual child_iterator
child_end();
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 virtual 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 virtual child_iterator
child_begin();
149 virtual child_iterator
child_end();
152 /// ObjCAtTryStmt - This represent objective-c's over-all
153 /// @try ... @catch ... @finally statement.
154 class ObjCAtTryStmt
: public Stmt
{
156 // The location of the
157 SourceLocation AtTryLoc
;
159 // The number of catch blocks in this statement.
160 unsigned NumCatchStmts
: 16;
162 // Whether this statement has a @finally statement.
165 /// \brief Retrieve the statements that are stored after this @try statement.
167 /// The order of the statements in memory follows the order in the source,
168 /// with the @try body first, followed by the @catch statements (if any) and,
169 /// finally, the @finally (if it exists).
170 Stmt
**getStmts() { return reinterpret_cast<Stmt
**> (this + 1); }
171 const Stmt
* const *getStmts() const {
172 return reinterpret_cast<const Stmt
* const*> (this + 1);
175 ObjCAtTryStmt(SourceLocation atTryLoc
, Stmt
*atTryStmt
,
176 Stmt
**CatchStmts
, unsigned NumCatchStmts
,
177 Stmt
*atFinallyStmt
);
179 explicit ObjCAtTryStmt(EmptyShell Empty
, unsigned NumCatchStmts
,
181 : Stmt(ObjCAtTryStmtClass
, Empty
), NumCatchStmts(NumCatchStmts
),
182 HasFinally(HasFinally
) { }
185 static ObjCAtTryStmt
*Create(ASTContext
&Context
, SourceLocation atTryLoc
,
187 Stmt
**CatchStmts
, unsigned NumCatchStmts
,
188 Stmt
*atFinallyStmt
);
189 static ObjCAtTryStmt
*CreateEmpty(ASTContext
&Context
,
190 unsigned NumCatchStmts
,
193 /// \brief Retrieve the location of the @ in the @try.
194 SourceLocation
getAtTryLoc() const { return AtTryLoc
; }
195 void setAtTryLoc(SourceLocation Loc
) { AtTryLoc
= Loc
; }
197 /// \brief Retrieve the @try body.
198 const Stmt
*getTryBody() const { return getStmts()[0]; }
199 Stmt
*getTryBody() { return getStmts()[0]; }
200 void setTryBody(Stmt
*S
) { getStmts()[0] = S
; }
202 /// \brief Retrieve the number of @catch statements in this try-catch-finally
204 unsigned getNumCatchStmts() const { return NumCatchStmts
; }
206 /// \brief Retrieve a @catch statement.
207 const ObjCAtCatchStmt
*getCatchStmt(unsigned I
) const {
208 assert(I
< NumCatchStmts
&& "Out-of-bounds @catch index");
209 return cast_or_null
<ObjCAtCatchStmt
>(getStmts()[I
+ 1]);
212 /// \brief Retrieve a @catch statement.
213 ObjCAtCatchStmt
*getCatchStmt(unsigned I
) {
214 assert(I
< NumCatchStmts
&& "Out-of-bounds @catch index");
215 return cast_or_null
<ObjCAtCatchStmt
>(getStmts()[I
+ 1]);
218 /// \brief Set a particular catch statement.
219 void setCatchStmt(unsigned I
, ObjCAtCatchStmt
*S
) {
220 assert(I
< NumCatchStmts
&& "Out-of-bounds @catch index");
221 getStmts()[I
+ 1] = S
;
224 /// Retrieve the @finally statement, if any.
225 const ObjCAtFinallyStmt
*getFinallyStmt() const {
229 return cast_or_null
<ObjCAtFinallyStmt
>(getStmts()[1 + NumCatchStmts
]);
231 ObjCAtFinallyStmt
*getFinallyStmt() {
235 return cast_or_null
<ObjCAtFinallyStmt
>(getStmts()[1 + NumCatchStmts
]);
237 void setFinallyStmt(Stmt
*S
) {
238 assert(HasFinally
&& "@try does not have a @finally slot!");
239 getStmts()[1 + NumCatchStmts
] = S
;
242 virtual SourceRange
getSourceRange() const;
244 static bool classof(const Stmt
*T
) {
245 return T
->getStmtClass() == ObjCAtTryStmtClass
;
247 static bool classof(const ObjCAtTryStmt
*) { return true; }
249 virtual child_iterator
child_begin();
250 virtual child_iterator
child_end();
253 /// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement.
254 /// Example: @synchronized (sem) {
258 class ObjCAtSynchronizedStmt
: public Stmt
{
260 enum { SYNC_EXPR
, SYNC_BODY
, END_EXPR
};
261 Stmt
* SubStmts
[END_EXPR
];
262 SourceLocation AtSynchronizedLoc
;
265 ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc
, Stmt
*synchExpr
,
267 : Stmt(ObjCAtSynchronizedStmtClass
) {
268 SubStmts
[SYNC_EXPR
] = synchExpr
;
269 SubStmts
[SYNC_BODY
] = synchBody
;
270 AtSynchronizedLoc
= atSynchronizedLoc
;
272 explicit ObjCAtSynchronizedStmt(EmptyShell Empty
) :
273 Stmt(ObjCAtSynchronizedStmtClass
, Empty
) { }
275 SourceLocation
getAtSynchronizedLoc() const { return AtSynchronizedLoc
; }
276 void setAtSynchronizedLoc(SourceLocation Loc
) { AtSynchronizedLoc
= Loc
; }
278 const CompoundStmt
*getSynchBody() const {
279 return reinterpret_cast<CompoundStmt
*>(SubStmts
[SYNC_BODY
]);
281 CompoundStmt
*getSynchBody() {
282 return reinterpret_cast<CompoundStmt
*>(SubStmts
[SYNC_BODY
]);
284 void setSynchBody(Stmt
*S
) { SubStmts
[SYNC_BODY
] = S
; }
286 const Expr
*getSynchExpr() const {
287 return reinterpret_cast<Expr
*>(SubStmts
[SYNC_EXPR
]);
289 Expr
*getSynchExpr() {
290 return reinterpret_cast<Expr
*>(SubStmts
[SYNC_EXPR
]);
292 void setSynchExpr(Stmt
*S
) { SubStmts
[SYNC_EXPR
] = S
; }
294 virtual SourceRange
getSourceRange() const {
295 return SourceRange(AtSynchronizedLoc
, getSynchBody()->getLocEnd());
298 static bool classof(const Stmt
*T
) {
299 return T
->getStmtClass() == ObjCAtSynchronizedStmtClass
;
301 static bool classof(const ObjCAtSynchronizedStmt
*) { return true; }
303 virtual child_iterator
child_begin();
304 virtual child_iterator
child_end();
307 /// ObjCAtThrowStmt - This represents objective-c's @throw statement.
308 class ObjCAtThrowStmt
: public Stmt
{
310 SourceLocation AtThrowLoc
;
312 ObjCAtThrowStmt(SourceLocation atThrowLoc
, Stmt
*throwExpr
)
313 : Stmt(ObjCAtThrowStmtClass
), Throw(throwExpr
) {
314 AtThrowLoc
= atThrowLoc
;
316 explicit ObjCAtThrowStmt(EmptyShell Empty
) :
317 Stmt(ObjCAtThrowStmtClass
, Empty
) { }
319 const Expr
*getThrowExpr() const { return reinterpret_cast<Expr
*>(Throw
); }
320 Expr
*getThrowExpr() { return reinterpret_cast<Expr
*>(Throw
); }
321 void setThrowExpr(Stmt
*S
) { Throw
= S
; }
323 SourceLocation
getThrowLoc() { return AtThrowLoc
; }
324 void setThrowLoc(SourceLocation Loc
) { AtThrowLoc
= Loc
; }
326 virtual SourceRange
getSourceRange() const {
328 return SourceRange(AtThrowLoc
, Throw
->getLocEnd());
330 return SourceRange(AtThrowLoc
);
333 static bool classof(const Stmt
*T
) {
334 return T
->getStmtClass() == ObjCAtThrowStmtClass
;
336 static bool classof(const ObjCAtThrowStmt
*) { return true; }
338 virtual child_iterator
child_begin();
339 virtual child_iterator
child_end();
342 } // end namespace clang