StmtObjC.h revision 809d1be9820039b4cf6efa48246a0d70ffa13394
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 20namespace clang { 21 22/// ObjCForCollectionStmt - This represents Objective-c's collection statement; 23/// represented as 'for (element 'in' collection-expression)' stmt. 24/// 25class 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; 30public: 31 ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body, 32 SourceLocation FCL, SourceLocation RPL); 33 explicit ObjCForCollectionStmt(EmptyShell Empty) : 34 Stmt(ObjCForCollectionStmtClass, Empty) { } 35 36 Stmt *getElement() { return SubExprs[ELEM]; } 37 Expr *getCollection() { 38 return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); 39 } 40 Stmt *getBody() { return SubExprs[BODY]; } 41 42 const Stmt *getElement() const { return SubExprs[ELEM]; } 43 const Expr *getCollection() const { 44 return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); 45 } 46 const Stmt *getBody() const { return SubExprs[BODY]; } 47 48 void setElement(Stmt *S) { SubExprs[ELEM] = S; } 49 void setCollection(Expr *E) { 50 SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(E); 51 } 52 void setBody(Stmt *S) { SubExprs[BODY] = S; } 53 54 SourceLocation getForLoc() const { return ForLoc; } 55 void setForLoc(SourceLocation Loc) { ForLoc = Loc; } 56 SourceLocation getRParenLoc() const { return RParenLoc; } 57 void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } 58 59 SourceRange getSourceRange() const LLVM_READONLY { 60 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 61 } 62 static bool classof(const Stmt *T) { 63 return T->getStmtClass() == ObjCForCollectionStmtClass; 64 } 65 static bool classof(const ObjCForCollectionStmt *) { return true; } 66 67 // Iterators 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. 74class ObjCAtCatchStmt : public Stmt { 75private: 76 VarDecl *ExceptionDecl; 77 Stmt *Body; 78 SourceLocation AtCatchLoc, RParenLoc; 79 80public: 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 87 explicit ObjCAtCatchStmt(EmptyShell Empty) : 88 Stmt(ObjCAtCatchStmtClass, Empty) { } 89 90 const Stmt *getCatchBody() const { return Body; } 91 Stmt *getCatchBody() { return Body; } 92 void setCatchBody(Stmt *S) { Body = S; } 93 94 const VarDecl *getCatchParamDecl() const { 95 return ExceptionDecl; 96 } 97 VarDecl *getCatchParamDecl() { 98 return ExceptionDecl; 99 } 100 void setCatchParamDecl(VarDecl *D) { ExceptionDecl = D; } 101 102 SourceLocation getAtCatchLoc() const { return AtCatchLoc; } 103 void setAtCatchLoc(SourceLocation Loc) { AtCatchLoc = Loc; } 104 SourceLocation getRParenLoc() const { return RParenLoc; } 105 void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } 106 107 SourceRange getSourceRange() const LLVM_READONLY { 108 return SourceRange(AtCatchLoc, Body->getLocEnd()); 109 } 110 111 bool hasEllipsis() const { return getCatchParamDecl() == 0; } 112 113 static bool classof(const Stmt *T) { 114 return T->getStmtClass() == ObjCAtCatchStmtClass; 115 } 116 static bool classof(const ObjCAtCatchStmt *) { return true; } 117 118 child_range children() { return child_range(&Body, &Body + 1); } 119}; 120 121/// ObjCAtFinallyStmt - This represent objective-c's \@finally Statement 122class ObjCAtFinallyStmt : public Stmt { 123 Stmt *AtFinallyStmt; 124 SourceLocation AtFinallyLoc; 125public: 126 ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt) 127 : Stmt(ObjCAtFinallyStmtClass), 128 AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {} 129 130 explicit ObjCAtFinallyStmt(EmptyShell Empty) : 131 Stmt(ObjCAtFinallyStmtClass, Empty) { } 132 133 const Stmt *getFinallyBody() const { return AtFinallyStmt; } 134 Stmt *getFinallyBody() { return AtFinallyStmt; } 135 void setFinallyBody(Stmt *S) { AtFinallyStmt = S; } 136 137 SourceRange getSourceRange() const LLVM_READONLY { 138 return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd()); 139 } 140 141 SourceLocation getAtFinallyLoc() const { return AtFinallyLoc; } 142 void setAtFinallyLoc(SourceLocation Loc) { AtFinallyLoc = Loc; } 143 144 static bool classof(const Stmt *T) { 145 return T->getStmtClass() == ObjCAtFinallyStmtClass; 146 } 147 static bool classof(const ObjCAtFinallyStmt *) { return true; } 148 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. 156class ObjCAtTryStmt : public Stmt { 157private: 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). 172 Stmt **getStmts() { return reinterpret_cast<Stmt **> (this + 1); } 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 181 explicit ObjCAtTryStmt(EmptyShell Empty, unsigned NumCatchStmts, 182 bool HasFinally) 183 : Stmt(ObjCAtTryStmtClass, Empty), NumCatchStmts(NumCatchStmts), 184 HasFinally(HasFinally) { } 185 186public: 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. 196 SourceLocation getAtTryLoc() const { return AtTryLoc; } 197 void setAtTryLoc(SourceLocation Loc) { AtTryLoc = Loc; } 198 199 /// \brief Retrieve the \@try body. 200 const Stmt *getTryBody() const { return getStmts()[0]; } 201 Stmt *getTryBody() { return getStmts()[0]; } 202 void setTryBody(Stmt *S) { getStmts()[0] = S; } 203 204 /// \brief Retrieve the number of \@catch statements in this try-catch-finally 205 /// block. 206 unsigned getNumCatchStmts() const { return NumCatchStmts; } 207 208 /// \brief Retrieve a \@catch statement. 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. 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. 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. 227 const ObjCAtFinallyStmt *getFinallyStmt() const { 228 if (!HasFinally) 229 return 0; 230 231 return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]); 232 } 233 ObjCAtFinallyStmt *getFinallyStmt() { 234 if (!HasFinally) 235 return 0; 236 237 return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]); 238 } 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 246 static bool classof(const Stmt *T) { 247 return T->getStmtClass() == ObjCAtTryStmtClass; 248 } 249 static bool classof(const ObjCAtTryStmt *) { return true; } 250 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/// 262class ObjCAtSynchronizedStmt : public Stmt { 263private: 264 enum { SYNC_EXPR, SYNC_BODY, END_EXPR }; 265 Stmt* SubStmts[END_EXPR]; 266 SourceLocation AtSynchronizedLoc; 267 268public: 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 } 276 explicit ObjCAtSynchronizedStmt(EmptyShell Empty) : 277 Stmt(ObjCAtSynchronizedStmtClass, Empty) { } 278 279 SourceLocation getAtSynchronizedLoc() const { return AtSynchronizedLoc; } 280 void setAtSynchronizedLoc(SourceLocation Loc) { AtSynchronizedLoc = Loc; } 281 282 const CompoundStmt *getSynchBody() const { 283 return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); 284 } 285 CompoundStmt *getSynchBody() { 286 return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); 287 } 288 void setSynchBody(Stmt *S) { SubStmts[SYNC_BODY] = S; } 289 290 const Expr *getSynchExpr() const { 291 return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); 292 } 293 Expr *getSynchExpr() { 294 return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); 295 } 296 void setSynchExpr(Stmt *S) { SubStmts[SYNC_EXPR] = S; } 297 298 SourceRange getSourceRange() const LLVM_READONLY { 299 return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd()); 300 } 301 302 static bool classof(const Stmt *T) { 303 return T->getStmtClass() == ObjCAtSynchronizedStmtClass; 304 } 305 static bool classof(const ObjCAtSynchronizedStmt *) { return true; } 306 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. 313class ObjCAtThrowStmt : public Stmt { 314 Stmt *Throw; 315 SourceLocation AtThrowLoc; 316public: 317 ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr) 318 : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) { 319 AtThrowLoc = atThrowLoc; 320 } 321 explicit ObjCAtThrowStmt(EmptyShell Empty) : 322 Stmt(ObjCAtThrowStmtClass, Empty) { } 323 324 const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); } 325 Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); } 326 void setThrowExpr(Stmt *S) { Throw = S; } 327 328 SourceLocation getThrowLoc() { return AtThrowLoc; } 329 void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; } 330 331 SourceRange getSourceRange() const LLVM_READONLY { 332 if (Throw) 333 return SourceRange(AtThrowLoc, Throw->getLocEnd()); 334 else 335 return SourceRange(AtThrowLoc); 336 } 337 338 static bool classof(const Stmt *T) { 339 return T->getStmtClass() == ObjCAtThrowStmtClass; 340 } 341 static bool classof(const ObjCAtThrowStmt *) { return true; } 342 343 child_range children() { return child_range(&Throw, &Throw+1); } 344}; 345 346/// ObjCAutoreleasePoolStmt - This represent objective-c's 347/// @autoreleasepool Statement 348class ObjCAutoreleasePoolStmt : public Stmt { 349 Stmt *SubStmt; 350 SourceLocation AtLoc; 351public: 352 ObjCAutoreleasePoolStmt(SourceLocation atLoc, 353 Stmt *subStmt) 354 : Stmt(ObjCAutoreleasePoolStmtClass), 355 SubStmt(subStmt), AtLoc(atLoc) {} 356 357 explicit ObjCAutoreleasePoolStmt(EmptyShell Empty) : 358 Stmt(ObjCAutoreleasePoolStmtClass, Empty) { } 359 360 const Stmt *getSubStmt() const { return SubStmt; } 361 Stmt *getSubStmt() { return SubStmt; } 362 void setSubStmt(Stmt *S) { SubStmt = S; } 363 364 SourceRange getSourceRange() const LLVM_READONLY { 365 return SourceRange(AtLoc, SubStmt->getLocEnd()); 366 } 367 368 SourceLocation getAtLoc() const { return AtLoc; } 369 void setAtLoc(SourceLocation Loc) { AtLoc = Loc; } 370 371 static bool classof(const Stmt *T) { 372 return T->getStmtClass() == ObjCAutoreleasePoolStmtClass; 373 } 374 static bool classof(const ObjCAutoreleasePoolStmt *) { return true; } 375 376 child_range children() { return child_range(&SubStmt, &SubStmt + 1); } 377}; 378 379} // end namespace clang 380 381#endif 382