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