Use the ASTMutationListener to track added template specializations in a chained...
[clang.git] / include / clang / AST / StmtObjC.h
blob269aa4c6dab2d1c8d8e5974dba4a00cb4577b343
1 //===--- StmtObjC.h - Classes for representing ObjC statements --*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
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"
19 namespace clang {
21 /// ObjCForCollectionStmt - This represents Objective-c's collection statement;
22 /// represented as 'for (element 'in' collection-expression)' stmt.
23 ///
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;
29 public:
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; }
66 // Iterators
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 {
73 private:
74 VarDecl *ExceptionDecl;
75 Stmt *Body;
76 SourceLocation AtCatchLoc, RParenLoc;
78 public:
79 ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
80 VarDecl *catchVarDecl,
81 Stmt *atCatchStmt)
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 {
93 return ExceptionDecl;
95 VarDecl *getCatchParamDecl() {
96 return ExceptionDecl;
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 {
122 Stmt *AtFinallyStmt;
123 SourceLocation AtFinallyLoc;
124 public:
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 {
155 private:
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.
163 bool HasFinally : 1;
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,
180 bool HasFinally)
181 : Stmt(ObjCAtTryStmtClass, Empty), NumCatchStmts(NumCatchStmts),
182 HasFinally(HasFinally) { }
184 public:
185 static ObjCAtTryStmt *Create(ASTContext &Context, SourceLocation atTryLoc,
186 Stmt *atTryStmt,
187 Stmt **CatchStmts, unsigned NumCatchStmts,
188 Stmt *atFinallyStmt);
189 static ObjCAtTryStmt *CreateEmpty(ASTContext &Context,
190 unsigned NumCatchStmts,
191 bool HasFinally);
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
203 /// block.
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 {
226 if (!HasFinally)
227 return 0;
229 return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
231 ObjCAtFinallyStmt *getFinallyStmt() {
232 if (!HasFinally)
233 return 0;
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) {
255 /// do-something;
256 /// }
258 class ObjCAtSynchronizedStmt : public Stmt {
259 private:
260 enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
261 Stmt* SubStmts[END_EXPR];
262 SourceLocation AtSynchronizedLoc;
264 public:
265 ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
266 Stmt *synchBody)
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 {
309 Stmt *Throw;
310 SourceLocation AtThrowLoc;
311 public:
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 {
327 if (Throw)
328 return SourceRange(AtThrowLoc, Throw->getLocEnd());
329 else
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
344 #endif