clang API Documentation

StmtObjC.h
Go to the documentation of this file.
00001 //===--- StmtObjC.h - Classes for representing ObjC statements --*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the Objective-C statement AST node classes.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_AST_STMTOBJC_H
00015 #define LLVM_CLANG_AST_STMTOBJC_H
00016 
00017 #include "clang/AST/Stmt.h"
00018 #include "llvm/Support/Compiler.h"
00019 
00020 namespace clang {
00021 
00022 /// ObjCForCollectionStmt - This represents Objective-c's collection statement;
00023 /// represented as 'for (element 'in' collection-expression)' stmt.
00024 ///
00025 class ObjCForCollectionStmt : public Stmt {
00026   enum { ELEM, COLLECTION, BODY, END_EXPR };
00027   Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt.
00028   SourceLocation ForLoc;
00029   SourceLocation RParenLoc;
00030 public:
00031   ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body,
00032                         SourceLocation FCL, SourceLocation RPL);
00033   explicit ObjCForCollectionStmt(EmptyShell Empty) :
00034     Stmt(ObjCForCollectionStmtClass, Empty) { }
00035 
00036   Stmt *getElement() { return SubExprs[ELEM]; }
00037   Expr *getCollection() {
00038     return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
00039   }
00040   Stmt *getBody() { return SubExprs[BODY]; }
00041 
00042   const Stmt *getElement() const { return SubExprs[ELEM]; }
00043   const Expr *getCollection() const {
00044     return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
00045   }
00046   const Stmt *getBody() const { return SubExprs[BODY]; }
00047 
00048   void setElement(Stmt *S) { SubExprs[ELEM] = S; }
00049   void setCollection(Expr *E) {
00050     SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(E);
00051   }
00052   void setBody(Stmt *S) { SubExprs[BODY] = S; }
00053 
00054   SourceLocation getForLoc() const { return ForLoc; }
00055   void setForLoc(SourceLocation Loc) { ForLoc = Loc; }
00056   SourceLocation getRParenLoc() const { return RParenLoc; }
00057   void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
00058 
00059   SourceRange getSourceRange() const LLVM_READONLY {
00060     return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
00061   }
00062   static bool classof(const Stmt *T) {
00063     return T->getStmtClass() == ObjCForCollectionStmtClass;
00064   }
00065   static bool classof(const ObjCForCollectionStmt *) { return true; }
00066 
00067   // Iterators
00068   child_range children() {
00069     return child_range(&SubExprs[0], &SubExprs[END_EXPR]);
00070   }
00071 };
00072 
00073 /// ObjCAtCatchStmt - This represents objective-c's @catch statement.
00074 class ObjCAtCatchStmt : public Stmt {
00075 private:
00076   VarDecl *ExceptionDecl;
00077   Stmt *Body;
00078   SourceLocation AtCatchLoc, RParenLoc;
00079 
00080 public:
00081   ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
00082                   VarDecl *catchVarDecl,
00083                   Stmt *atCatchStmt)
00084     : Stmt(ObjCAtCatchStmtClass), ExceptionDecl(catchVarDecl), 
00085     Body(atCatchStmt), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) { }
00086 
00087   explicit ObjCAtCatchStmt(EmptyShell Empty) :
00088     Stmt(ObjCAtCatchStmtClass, Empty) { }
00089 
00090   const Stmt *getCatchBody() const { return Body; }
00091   Stmt *getCatchBody() { return Body; }
00092   void setCatchBody(Stmt *S) { Body = S; }
00093 
00094   const VarDecl *getCatchParamDecl() const {
00095     return ExceptionDecl;
00096   }
00097   VarDecl *getCatchParamDecl() {
00098     return ExceptionDecl;
00099   }
00100   void setCatchParamDecl(VarDecl *D) { ExceptionDecl = D; }
00101 
00102   SourceLocation getAtCatchLoc() const { return AtCatchLoc; }
00103   void setAtCatchLoc(SourceLocation Loc) { AtCatchLoc = Loc; }
00104   SourceLocation getRParenLoc() const { return RParenLoc; }
00105   void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
00106 
00107   SourceRange getSourceRange() const LLVM_READONLY {
00108     return SourceRange(AtCatchLoc, Body->getLocEnd());
00109   }
00110 
00111   bool hasEllipsis() const { return getCatchParamDecl() == 0; }
00112 
00113   static bool classof(const Stmt *T) {
00114     return T->getStmtClass() == ObjCAtCatchStmtClass;
00115   }
00116   static bool classof(const ObjCAtCatchStmt *) { return true; }
00117 
00118   child_range children() { return child_range(&Body, &Body + 1); }
00119 };
00120 
00121 /// ObjCAtFinallyStmt - This represent objective-c's @finally Statement
00122 class ObjCAtFinallyStmt : public Stmt {
00123   Stmt *AtFinallyStmt;
00124   SourceLocation AtFinallyLoc;
00125 public:
00126   ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
00127   : Stmt(ObjCAtFinallyStmtClass),
00128     AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
00129 
00130   explicit ObjCAtFinallyStmt(EmptyShell Empty) :
00131     Stmt(ObjCAtFinallyStmtClass, Empty) { }
00132 
00133   const Stmt *getFinallyBody() const { return AtFinallyStmt; }
00134   Stmt *getFinallyBody() { return AtFinallyStmt; }
00135   void setFinallyBody(Stmt *S) { AtFinallyStmt = S; }
00136 
00137   SourceRange getSourceRange() const LLVM_READONLY {
00138     return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd());
00139   }
00140 
00141   SourceLocation getAtFinallyLoc() const { return AtFinallyLoc; }
00142   void setAtFinallyLoc(SourceLocation Loc) { AtFinallyLoc = Loc; }
00143 
00144   static bool classof(const Stmt *T) {
00145     return T->getStmtClass() == ObjCAtFinallyStmtClass;
00146   }
00147   static bool classof(const ObjCAtFinallyStmt *) { return true; }
00148 
00149   child_range children() {
00150     return child_range(&AtFinallyStmt, &AtFinallyStmt+1);
00151   }
00152 };
00153 
00154 /// ObjCAtTryStmt - This represent objective-c's over-all
00155 /// @try ... @catch ... @finally statement.
00156 class ObjCAtTryStmt : public Stmt {
00157 private:
00158   // The location of the 
00159   SourceLocation AtTryLoc;
00160   
00161   // The number of catch blocks in this statement.
00162   unsigned NumCatchStmts : 16;
00163   
00164   // Whether this statement has a @finally statement.
00165   bool HasFinally : 1;
00166   
00167   /// \brief Retrieve the statements that are stored after this @try statement.
00168   ///
00169   /// The order of the statements in memory follows the order in the source,
00170   /// with the @try body first, followed by the @catch statements (if any) and,
00171   /// finally, the @finally (if it exists).
00172   Stmt **getStmts() { return reinterpret_cast<Stmt **> (this + 1); }
00173   const Stmt* const *getStmts() const { 
00174     return reinterpret_cast<const Stmt * const*> (this + 1); 
00175   }
00176   
00177   ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
00178                 Stmt **CatchStmts, unsigned NumCatchStmts,
00179                 Stmt *atFinallyStmt);
00180   
00181   explicit ObjCAtTryStmt(EmptyShell Empty, unsigned NumCatchStmts,
00182                          bool HasFinally)
00183     : Stmt(ObjCAtTryStmtClass, Empty), NumCatchStmts(NumCatchStmts),
00184       HasFinally(HasFinally) { }
00185 
00186 public:
00187   static ObjCAtTryStmt *Create(ASTContext &Context, SourceLocation atTryLoc, 
00188                                Stmt *atTryStmt,
00189                                Stmt **CatchStmts, unsigned NumCatchStmts,
00190                                Stmt *atFinallyStmt);
00191   static ObjCAtTryStmt *CreateEmpty(ASTContext &Context, 
00192                                     unsigned NumCatchStmts,
00193                                     bool HasFinally);
00194   
00195   /// \brief Retrieve the location of the @ in the @try.
00196   SourceLocation getAtTryLoc() const { return AtTryLoc; }
00197   void setAtTryLoc(SourceLocation Loc) { AtTryLoc = Loc; }
00198 
00199   /// \brief Retrieve the @try body.
00200   const Stmt *getTryBody() const { return getStmts()[0]; }
00201   Stmt *getTryBody() { return getStmts()[0]; }
00202   void setTryBody(Stmt *S) { getStmts()[0] = S; }
00203 
00204   /// \brief Retrieve the number of @catch statements in this try-catch-finally
00205   /// block.
00206   unsigned getNumCatchStmts() const { return NumCatchStmts; }
00207   
00208   /// \brief Retrieve a @catch statement.
00209   const ObjCAtCatchStmt *getCatchStmt(unsigned I) const {
00210     assert(I < NumCatchStmts && "Out-of-bounds @catch index");
00211     return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
00212   }
00213   
00214   /// \brief Retrieve a @catch statement.
00215   ObjCAtCatchStmt *getCatchStmt(unsigned I) {
00216     assert(I < NumCatchStmts && "Out-of-bounds @catch index");
00217     return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
00218   }
00219   
00220   /// \brief Set a particular catch statement.
00221   void setCatchStmt(unsigned I, ObjCAtCatchStmt *S) {
00222     assert(I < NumCatchStmts && "Out-of-bounds @catch index");
00223     getStmts()[I + 1] = S;
00224   }
00225   
00226   /// Retrieve the @finally statement, if any.
00227   const ObjCAtFinallyStmt *getFinallyStmt() const {
00228     if (!HasFinally)
00229       return 0;
00230     
00231     return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
00232   }
00233   ObjCAtFinallyStmt *getFinallyStmt() {
00234     if (!HasFinally)
00235       return 0;
00236     
00237     return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
00238   }
00239   void setFinallyStmt(Stmt *S) { 
00240     assert(HasFinally && "@try does not have a @finally slot!");
00241     getStmts()[1 + NumCatchStmts] = S; 
00242   }
00243 
00244   SourceRange getSourceRange() const LLVM_READONLY;
00245 
00246   static bool classof(const Stmt *T) {
00247     return T->getStmtClass() == ObjCAtTryStmtClass;
00248   }
00249   static bool classof(const ObjCAtTryStmt *) { return true; }
00250 
00251   child_range children() {
00252     return child_range(getStmts(),
00253                        getStmts() + 1 + NumCatchStmts + HasFinally);
00254   }
00255 };
00256 
00257 /// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement.
00258 /// Example: @synchronized (sem) {
00259 ///             do-something;
00260 ///          }
00261 ///
00262 class ObjCAtSynchronizedStmt : public Stmt {
00263 private:
00264   enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
00265   Stmt* SubStmts[END_EXPR];
00266   SourceLocation AtSynchronizedLoc;
00267 
00268 public:
00269   ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
00270                          Stmt *synchBody)
00271   : Stmt(ObjCAtSynchronizedStmtClass) {
00272     SubStmts[SYNC_EXPR] = synchExpr;
00273     SubStmts[SYNC_BODY] = synchBody;
00274     AtSynchronizedLoc = atSynchronizedLoc;
00275   }
00276   explicit ObjCAtSynchronizedStmt(EmptyShell Empty) :
00277     Stmt(ObjCAtSynchronizedStmtClass, Empty) { }
00278 
00279   SourceLocation getAtSynchronizedLoc() const { return AtSynchronizedLoc; }
00280   void setAtSynchronizedLoc(SourceLocation Loc) { AtSynchronizedLoc = Loc; }
00281 
00282   const CompoundStmt *getSynchBody() const {
00283     return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
00284   }
00285   CompoundStmt *getSynchBody() {
00286     return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
00287   }
00288   void setSynchBody(Stmt *S) { SubStmts[SYNC_BODY] = S; }
00289 
00290   const Expr *getSynchExpr() const {
00291     return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
00292   }
00293   Expr *getSynchExpr() {
00294     return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
00295   }
00296   void setSynchExpr(Stmt *S) { SubStmts[SYNC_EXPR] = S; }
00297 
00298   SourceRange getSourceRange() const LLVM_READONLY {
00299     return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd());
00300   }
00301 
00302   static bool classof(const Stmt *T) {
00303     return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
00304   }
00305   static bool classof(const ObjCAtSynchronizedStmt *) { return true; }
00306 
00307   child_range children() {
00308     return child_range(&SubStmts[0], &SubStmts[0]+END_EXPR);
00309   }
00310 };
00311 
00312 /// ObjCAtThrowStmt - This represents objective-c's @throw statement.
00313 class ObjCAtThrowStmt : public Stmt {
00314   Stmt *Throw;
00315   SourceLocation AtThrowLoc;
00316 public:
00317   ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
00318   : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) {
00319     AtThrowLoc = atThrowLoc;
00320   }
00321   explicit ObjCAtThrowStmt(EmptyShell Empty) :
00322     Stmt(ObjCAtThrowStmtClass, Empty) { }
00323 
00324   const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
00325   Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); }
00326   void setThrowExpr(Stmt *S) { Throw = S; }
00327 
00328   SourceLocation getThrowLoc() { return AtThrowLoc; }
00329   void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; }
00330 
00331   SourceRange getSourceRange() const LLVM_READONLY {
00332     if (Throw)
00333       return SourceRange(AtThrowLoc, Throw->getLocEnd());
00334     else
00335       return SourceRange(AtThrowLoc);
00336   }
00337 
00338   static bool classof(const Stmt *T) {
00339     return T->getStmtClass() == ObjCAtThrowStmtClass;
00340   }
00341   static bool classof(const ObjCAtThrowStmt *) { return true; }
00342 
00343   child_range children() { return child_range(&Throw, &Throw+1); }
00344 };
00345 
00346 /// ObjCAutoreleasePoolStmt - This represent objective-c's 
00347 /// @autoreleasepool Statement
00348 class ObjCAutoreleasePoolStmt : public Stmt {
00349   Stmt *SubStmt;
00350   SourceLocation AtLoc;
00351 public:
00352   ObjCAutoreleasePoolStmt(SourceLocation atLoc, 
00353                             Stmt *subStmt)
00354   : Stmt(ObjCAutoreleasePoolStmtClass),
00355     SubStmt(subStmt), AtLoc(atLoc) {}
00356 
00357   explicit ObjCAutoreleasePoolStmt(EmptyShell Empty) :
00358     Stmt(ObjCAutoreleasePoolStmtClass, Empty) { }
00359 
00360   const Stmt *getSubStmt() const { return SubStmt; }
00361   Stmt *getSubStmt() { return SubStmt; }
00362   void setSubStmt(Stmt *S) { SubStmt = S; }
00363 
00364   SourceRange getSourceRange() const LLVM_READONLY {
00365     return SourceRange(AtLoc, SubStmt->getLocEnd());
00366   }
00367 
00368   SourceLocation getAtLoc() const { return AtLoc; }
00369   void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
00370 
00371   static bool classof(const Stmt *T) {
00372     return T->getStmtClass() == ObjCAutoreleasePoolStmtClass;
00373   }
00374   static bool classof(const ObjCAutoreleasePoolStmt *) { return true; }
00375 
00376   child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
00377 };
00378 
00379 }  // end namespace clang
00380 
00381 #endif