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