clang API Documentation
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