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 /// \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