- //===--- StmtObjC.h - Classes for representing ObjC statements --*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
-   
- /// \file 
- /// Defines the Objective-C statement AST node classes. 
-   
- #ifndef LLVM_CLANG_AST_STMTOBJC_H 
- #define LLVM_CLANG_AST_STMTOBJC_H 
-   
- #include "clang/AST/Stmt.h" 
- #include "llvm/Support/Compiler.h" 
-   
- namespace clang { 
-   
- /// Represents Objective-C's collection statement. 
- /// 
- /// This is represented as 'for (element 'in' collection-expression)' stmt. 
- class ObjCForCollectionStmt : public Stmt { 
-   enum { ELEM, COLLECTION, BODY, END_EXPR }; 
-   Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt. 
-   SourceLocation ForLoc; 
-   SourceLocation RParenLoc; 
- public: 
-   ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body, 
-                         SourceLocation FCL, SourceLocation RPL); 
-   explicit ObjCForCollectionStmt(EmptyShell Empty) : 
-     Stmt(ObjCForCollectionStmtClass, Empty) { } 
-   
-   Stmt *getElement() { return SubExprs[ELEM]; } 
-   Expr *getCollection() { 
-     return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); 
-   } 
-   Stmt *getBody() { return SubExprs[BODY]; } 
-   
-   const Stmt *getElement() const { return SubExprs[ELEM]; } 
-   const Expr *getCollection() const { 
-     return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); 
-   } 
-   const Stmt *getBody() const { return SubExprs[BODY]; } 
-   
-   void setElement(Stmt *S) { SubExprs[ELEM] = S; } 
-   void setCollection(Expr *E) { 
-     SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(E); 
-   } 
-   void setBody(Stmt *S) { SubExprs[BODY] = S; } 
-   
-   SourceLocation getForLoc() const { return ForLoc; } 
-   void setForLoc(SourceLocation Loc) { ForLoc = Loc; } 
-   SourceLocation getRParenLoc() const { return RParenLoc; } 
-   void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return ForLoc; } 
-   SourceLocation getEndLoc() const LLVM_READONLY { 
-     return SubExprs[BODY]->getEndLoc(); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCForCollectionStmtClass; 
-   } 
-   
-   // Iterators 
-   child_range children() { 
-     return child_range(&SubExprs[0], &SubExprs[END_EXPR]); 
-   } 
-   
-   const_child_range children() const { 
-     return const_child_range(&SubExprs[0], &SubExprs[END_EXPR]); 
-   } 
- }; 
-   
- /// Represents Objective-C's \@catch statement. 
- class ObjCAtCatchStmt : public Stmt { 
- private: 
-   VarDecl *ExceptionDecl; 
-   Stmt *Body; 
-   SourceLocation AtCatchLoc, RParenLoc; 
-   
- public: 
-   ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc, 
-                   VarDecl *catchVarDecl, 
-                   Stmt *atCatchStmt) 
-     : Stmt(ObjCAtCatchStmtClass), ExceptionDecl(catchVarDecl), 
-     Body(atCatchStmt), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) { } 
-   
-   explicit ObjCAtCatchStmt(EmptyShell Empty) : 
-     Stmt(ObjCAtCatchStmtClass, Empty) { } 
-   
-   const Stmt *getCatchBody() const { return Body; } 
-   Stmt *getCatchBody() { return Body; } 
-   void setCatchBody(Stmt *S) { Body = S; } 
-   
-   const VarDecl *getCatchParamDecl() const { 
-     return ExceptionDecl; 
-   } 
-   VarDecl *getCatchParamDecl() { 
-     return ExceptionDecl; 
-   } 
-   void setCatchParamDecl(VarDecl *D) { ExceptionDecl = D; } 
-   
-   SourceLocation getAtCatchLoc() const { return AtCatchLoc; } 
-   void setAtCatchLoc(SourceLocation Loc) { AtCatchLoc = Loc; } 
-   SourceLocation getRParenLoc() const { return RParenLoc; } 
-   void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return AtCatchLoc; } 
-   SourceLocation getEndLoc() const LLVM_READONLY { return Body->getEndLoc(); } 
-   
-   bool hasEllipsis() const { return getCatchParamDecl() == nullptr; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCAtCatchStmtClass; 
-   } 
-   
-   child_range children() { return child_range(&Body, &Body + 1); } 
-   
-   const_child_range children() const { 
-     return const_child_range(&Body, &Body + 1); 
-   } 
- }; 
-   
- /// Represents Objective-C's \@finally statement 
- class ObjCAtFinallyStmt : public Stmt { 
-   SourceLocation AtFinallyLoc; 
-   Stmt *AtFinallyStmt; 
-   
- public: 
-   ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt) 
-       : Stmt(ObjCAtFinallyStmtClass), AtFinallyLoc(atFinallyLoc), 
-         AtFinallyStmt(atFinallyStmt) {} 
-   
-   explicit ObjCAtFinallyStmt(EmptyShell Empty) : 
-     Stmt(ObjCAtFinallyStmtClass, Empty) { } 
-   
-   const Stmt *getFinallyBody() const { return AtFinallyStmt; } 
-   Stmt *getFinallyBody() { return AtFinallyStmt; } 
-   void setFinallyBody(Stmt *S) { AtFinallyStmt = S; } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return AtFinallyLoc; } 
-   SourceLocation getEndLoc() const LLVM_READONLY { 
-     return AtFinallyStmt->getEndLoc(); 
-   } 
-   
-   SourceLocation getAtFinallyLoc() const { return AtFinallyLoc; } 
-   void setAtFinallyLoc(SourceLocation Loc) { AtFinallyLoc = Loc; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCAtFinallyStmtClass; 
-   } 
-   
-   child_range children() { 
-     return child_range(&AtFinallyStmt, &AtFinallyStmt+1); 
-   } 
-   
-   const_child_range children() const { 
-     return const_child_range(&AtFinallyStmt, &AtFinallyStmt + 1); 
-   } 
- }; 
-   
- /// Represents Objective-C's \@try ... \@catch ... \@finally statement. 
- class ObjCAtTryStmt final 
-     : public Stmt, 
-       private llvm::TrailingObjects<ObjCAtTryStmt, Stmt *> { 
-   friend TrailingObjects; 
-   size_t numTrailingObjects(OverloadToken<Stmt *>) const { 
-     return 1 + NumCatchStmts + HasFinally; 
-   } 
-   
-   // The location of the @ in the \@try. 
-   SourceLocation AtTryLoc; 
-   
-   // The number of catch blocks in this statement. 
-   unsigned NumCatchStmts : 16; 
-   
-   // Whether this statement has a \@finally statement. 
-   bool HasFinally : 1; 
-   
-   /// Retrieve the statements that are stored after this \@try statement. 
-   /// 
-   /// The order of the statements in memory follows the order in the source, 
-   /// with the \@try body first, followed by the \@catch statements (if any) 
-   /// and, finally, the \@finally (if it exists). 
-   Stmt **getStmts() { return getTrailingObjects<Stmt *>(); } 
-   Stmt *const *getStmts() const { return getTrailingObjects<Stmt *>(); } 
-   
-   ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, 
-                 Stmt **CatchStmts, unsigned NumCatchStmts, 
-                 Stmt *atFinallyStmt); 
-   
-   explicit ObjCAtTryStmt(EmptyShell Empty, unsigned NumCatchStmts, 
-                          bool HasFinally) 
-     : Stmt(ObjCAtTryStmtClass, Empty), NumCatchStmts(NumCatchStmts), 
-       HasFinally(HasFinally) { } 
-   
- public: 
-   static ObjCAtTryStmt *Create(const ASTContext &Context, 
-                                SourceLocation atTryLoc, Stmt *atTryStmt, 
-                                Stmt **CatchStmts, unsigned NumCatchStmts, 
-                                Stmt *atFinallyStmt); 
-   static ObjCAtTryStmt *CreateEmpty(const ASTContext &Context, 
-                                     unsigned NumCatchStmts, bool HasFinally); 
-   
-   /// Retrieve the location of the @ in the \@try. 
-   SourceLocation getAtTryLoc() const { return AtTryLoc; } 
-   void setAtTryLoc(SourceLocation Loc) { AtTryLoc = Loc; } 
-   
-   /// Retrieve the \@try body. 
-   const Stmt *getTryBody() const { return getStmts()[0]; } 
-   Stmt *getTryBody() { return getStmts()[0]; } 
-   void setTryBody(Stmt *S) { getStmts()[0] = S; } 
-   
-   /// Retrieve the number of \@catch statements in this try-catch-finally 
-   /// block. 
-   unsigned getNumCatchStmts() const { return NumCatchStmts; } 
-   
-   /// Retrieve a \@catch statement. 
-   const ObjCAtCatchStmt *getCatchStmt(unsigned I) const { 
-     assert(I < NumCatchStmts && "Out-of-bounds @catch index"); 
-     return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]); 
-   } 
-   
-   /// Retrieve a \@catch statement. 
-   ObjCAtCatchStmt *getCatchStmt(unsigned I) { 
-     assert(I < NumCatchStmts && "Out-of-bounds @catch index"); 
-     return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]); 
-   } 
-   
-   /// Set a particular catch statement. 
-   void setCatchStmt(unsigned I, ObjCAtCatchStmt *S) { 
-     assert(I < NumCatchStmts && "Out-of-bounds @catch index"); 
-     getStmts()[I + 1] = S; 
-   } 
-   
-   /// Retrieve the \@finally statement, if any. 
-   const ObjCAtFinallyStmt *getFinallyStmt() const { 
-     if (!HasFinally) 
-       return nullptr; 
-   
-     return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]); 
-   } 
-   ObjCAtFinallyStmt *getFinallyStmt() { 
-     if (!HasFinally) 
-       return nullptr; 
-   
-     return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]); 
-   } 
-   void setFinallyStmt(Stmt *S) { 
-     assert(HasFinally && "@try does not have a @finally slot!"); 
-     getStmts()[1 + NumCatchStmts] = S; 
-   } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return AtTryLoc; } 
-   SourceLocation getEndLoc() const LLVM_READONLY; 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCAtTryStmtClass; 
-   } 
-   
-   child_range children() { 
-     return child_range( 
-         getStmts(), getStmts() + numTrailingObjects(OverloadToken<Stmt *>())); 
-   } 
-   
-   const_child_range children() const { 
-     return const_child_range(const_cast<ObjCAtTryStmt *>(this)->children()); 
-   } 
-   
-   using catch_stmt_iterator = CastIterator<ObjCAtCatchStmt>; 
-   using const_catch_stmt_iterator = ConstCastIterator<ObjCAtCatchStmt>; 
-   using catch_range = llvm::iterator_range<catch_stmt_iterator>; 
-   using catch_const_range = llvm::iterator_range<const_catch_stmt_iterator>; 
-   
-   catch_stmt_iterator catch_stmts_begin() { return getStmts() + 1; } 
-   catch_stmt_iterator catch_stmts_end() { 
-     return catch_stmts_begin() + NumCatchStmts; 
-   } 
-   catch_range catch_stmts() { 
-     return catch_range(catch_stmts_begin(), catch_stmts_end()); 
-   } 
-   
-   const_catch_stmt_iterator catch_stmts_begin() const { return getStmts() + 1; } 
-   const_catch_stmt_iterator catch_stmts_end() const { 
-     return catch_stmts_begin() + NumCatchStmts; 
-   } 
-   catch_const_range catch_stmts() const { 
-     return catch_const_range(catch_stmts_begin(), catch_stmts_end()); 
-   } 
- }; 
-   
- /// Represents Objective-C's \@synchronized statement. 
- /// 
- /// Example: 
- /// \code 
- ///   @synchronized (sem) { 
- ///     do-something; 
- ///   } 
- /// \endcode 
- class ObjCAtSynchronizedStmt : public Stmt { 
- private: 
-   SourceLocation AtSynchronizedLoc; 
-   enum { SYNC_EXPR, SYNC_BODY, END_EXPR }; 
-   Stmt* SubStmts[END_EXPR]; 
-   
- public: 
-   ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr, 
-                          Stmt *synchBody) 
-   : Stmt(ObjCAtSynchronizedStmtClass) { 
-     SubStmts[SYNC_EXPR] = synchExpr; 
-     SubStmts[SYNC_BODY] = synchBody; 
-     AtSynchronizedLoc = atSynchronizedLoc; 
-   } 
-   explicit ObjCAtSynchronizedStmt(EmptyShell Empty) : 
-     Stmt(ObjCAtSynchronizedStmtClass, Empty) { } 
-   
-   SourceLocation getAtSynchronizedLoc() const { return AtSynchronizedLoc; } 
-   void setAtSynchronizedLoc(SourceLocation Loc) { AtSynchronizedLoc = Loc; } 
-   
-   const CompoundStmt *getSynchBody() const { 
-     return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); 
-   } 
-   CompoundStmt *getSynchBody() { 
-     return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); 
-   } 
-   void setSynchBody(Stmt *S) { SubStmts[SYNC_BODY] = S; } 
-   
-   const Expr *getSynchExpr() const { 
-     return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); 
-   } 
-   Expr *getSynchExpr() { 
-     return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); 
-   } 
-   void setSynchExpr(Stmt *S) { SubStmts[SYNC_EXPR] = S; } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return AtSynchronizedLoc; } 
-   SourceLocation getEndLoc() const LLVM_READONLY { 
-     return getSynchBody()->getEndLoc(); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCAtSynchronizedStmtClass; 
-   } 
-   
-   child_range children() { 
-     return child_range(&SubStmts[0], &SubStmts[0]+END_EXPR); 
-   } 
-   
-   const_child_range children() const { 
-     return const_child_range(&SubStmts[0], &SubStmts[0] + END_EXPR); 
-   } 
- }; 
-   
- /// Represents Objective-C's \@throw statement. 
- class ObjCAtThrowStmt : public Stmt { 
-   SourceLocation AtThrowLoc; 
-   Stmt *Throw; 
-   
- public: 
-   ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr) 
-   : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) { 
-     AtThrowLoc = atThrowLoc; 
-   } 
-   explicit ObjCAtThrowStmt(EmptyShell Empty) : 
-     Stmt(ObjCAtThrowStmtClass, Empty) { } 
-   
-   const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); } 
-   Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); } 
-   void setThrowExpr(Stmt *S) { Throw = S; } 
-   
-   SourceLocation getThrowLoc() const LLVM_READONLY { return AtThrowLoc; } 
-   void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return AtThrowLoc; } 
-   SourceLocation getEndLoc() const LLVM_READONLY { 
-     return Throw ? Throw->getEndLoc() : AtThrowLoc; 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCAtThrowStmtClass; 
-   } 
-   
-   child_range children() { return child_range(&Throw, &Throw+1); } 
-   
-   const_child_range children() const { 
-     return const_child_range(&Throw, &Throw + 1); 
-   } 
- }; 
-   
- /// Represents Objective-C's \@autoreleasepool Statement 
- class ObjCAutoreleasePoolStmt : public Stmt { 
-   SourceLocation AtLoc; 
-   Stmt *SubStmt; 
-   
- public: 
-   ObjCAutoreleasePoolStmt(SourceLocation atLoc, Stmt *subStmt) 
-       : Stmt(ObjCAutoreleasePoolStmtClass), AtLoc(atLoc), SubStmt(subStmt) {} 
-   
-   explicit ObjCAutoreleasePoolStmt(EmptyShell Empty) : 
-     Stmt(ObjCAutoreleasePoolStmtClass, Empty) { } 
-   
-   const Stmt *getSubStmt() const { return SubStmt; } 
-   Stmt *getSubStmt() { return SubStmt; } 
-   void setSubStmt(Stmt *S) { SubStmt = S; } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; } 
-   SourceLocation getEndLoc() const LLVM_READONLY { 
-     return SubStmt->getEndLoc(); 
-   } 
-   
-   SourceLocation getAtLoc() const { return AtLoc; } 
-   void setAtLoc(SourceLocation Loc) { AtLoc = Loc; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == ObjCAutoreleasePoolStmtClass; 
-   } 
-   
-   child_range children() { return child_range(&SubStmt, &SubStmt + 1); } 
-   
-   const_child_range children() const { 
-     return const_child_range(&SubStmt, &SubStmt + 1); 
-   } 
- }; 
-   
- }  // end namespace clang 
-   
- #endif 
-