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