Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:42

0001 //===--- StmtObjC.h - Classes for representing ObjC statements --*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 /// \file
0010 /// Defines the Objective-C statement AST node classes.
0011 
0012 #ifndef LLVM_CLANG_AST_STMTOBJC_H
0013 #define LLVM_CLANG_AST_STMTOBJC_H
0014 
0015 #include "clang/AST/Stmt.h"
0016 #include "llvm/Support/Compiler.h"
0017 
0018 namespace clang {
0019 
0020 /// Represents Objective-C's collection statement.
0021 ///
0022 /// This is represented as 'for (element 'in' collection-expression)' stmt.
0023 class ObjCForCollectionStmt : public Stmt {
0024   enum { ELEM, COLLECTION, BODY, END_EXPR };
0025   Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt.
0026   SourceLocation ForLoc;
0027   SourceLocation RParenLoc;
0028 public:
0029   ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body,
0030                         SourceLocation FCL, SourceLocation RPL);
0031   explicit ObjCForCollectionStmt(EmptyShell Empty) :
0032     Stmt(ObjCForCollectionStmtClass, Empty) { }
0033 
0034   Stmt *getElement() { return SubExprs[ELEM]; }
0035   Expr *getCollection() {
0036     return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
0037   }
0038   Stmt *getBody() { return SubExprs[BODY]; }
0039 
0040   const Stmt *getElement() const { return SubExprs[ELEM]; }
0041   const Expr *getCollection() const {
0042     return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
0043   }
0044   const Stmt *getBody() const { return SubExprs[BODY]; }
0045 
0046   void setElement(Stmt *S) { SubExprs[ELEM] = S; }
0047   void setCollection(Expr *E) {
0048     SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(E);
0049   }
0050   void setBody(Stmt *S) { SubExprs[BODY] = S; }
0051 
0052   SourceLocation getForLoc() const { return ForLoc; }
0053   void setForLoc(SourceLocation Loc) { ForLoc = Loc; }
0054   SourceLocation getRParenLoc() const { return RParenLoc; }
0055   void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
0056 
0057   SourceLocation getBeginLoc() const LLVM_READONLY { return ForLoc; }
0058   SourceLocation getEndLoc() const LLVM_READONLY {
0059     return SubExprs[BODY]->getEndLoc();
0060   }
0061 
0062   static bool classof(const Stmt *T) {
0063     return T->getStmtClass() == ObjCForCollectionStmtClass;
0064   }
0065 
0066   // Iterators
0067   child_range children() {
0068     return child_range(&SubExprs[0], &SubExprs[END_EXPR]);
0069   }
0070 
0071   const_child_range children() const {
0072     return const_child_range(&SubExprs[0], &SubExprs[END_EXPR]);
0073   }
0074 };
0075 
0076 /// Represents Objective-C's \@catch statement.
0077 class ObjCAtCatchStmt : public Stmt {
0078 private:
0079   VarDecl *ExceptionDecl;
0080   Stmt *Body;
0081   SourceLocation AtCatchLoc, RParenLoc;
0082 
0083 public:
0084   ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
0085                   VarDecl *catchVarDecl,
0086                   Stmt *atCatchStmt)
0087     : Stmt(ObjCAtCatchStmtClass), ExceptionDecl(catchVarDecl),
0088     Body(atCatchStmt), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) { }
0089 
0090   explicit ObjCAtCatchStmt(EmptyShell Empty) :
0091     Stmt(ObjCAtCatchStmtClass, Empty) { }
0092 
0093   const Stmt *getCatchBody() const { return Body; }
0094   Stmt *getCatchBody() { return Body; }
0095   void setCatchBody(Stmt *S) { Body = S; }
0096 
0097   const VarDecl *getCatchParamDecl() const {
0098     return ExceptionDecl;
0099   }
0100   VarDecl *getCatchParamDecl() {
0101     return ExceptionDecl;
0102   }
0103   void setCatchParamDecl(VarDecl *D) { ExceptionDecl = D; }
0104 
0105   SourceLocation getAtCatchLoc() const { return AtCatchLoc; }
0106   void setAtCatchLoc(SourceLocation Loc) { AtCatchLoc = Loc; }
0107   SourceLocation getRParenLoc() const { return RParenLoc; }
0108   void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
0109 
0110   SourceLocation getBeginLoc() const LLVM_READONLY { return AtCatchLoc; }
0111   SourceLocation getEndLoc() const LLVM_READONLY { return Body->getEndLoc(); }
0112 
0113   bool hasEllipsis() const { return getCatchParamDecl() == nullptr; }
0114 
0115   static bool classof(const Stmt *T) {
0116     return T->getStmtClass() == ObjCAtCatchStmtClass;
0117   }
0118 
0119   child_range children() { return child_range(&Body, &Body + 1); }
0120 
0121   const_child_range children() const {
0122     return const_child_range(&Body, &Body + 1);
0123   }
0124 };
0125 
0126 /// Represents Objective-C's \@finally statement
0127 class ObjCAtFinallyStmt : public Stmt {
0128   SourceLocation AtFinallyLoc;
0129   Stmt *AtFinallyStmt;
0130 
0131 public:
0132   ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
0133       : Stmt(ObjCAtFinallyStmtClass), AtFinallyLoc(atFinallyLoc),
0134         AtFinallyStmt(atFinallyStmt) {}
0135 
0136   explicit ObjCAtFinallyStmt(EmptyShell Empty) :
0137     Stmt(ObjCAtFinallyStmtClass, Empty) { }
0138 
0139   const Stmt *getFinallyBody() const { return AtFinallyStmt; }
0140   Stmt *getFinallyBody() { return AtFinallyStmt; }
0141   void setFinallyBody(Stmt *S) { AtFinallyStmt = S; }
0142 
0143   SourceLocation getBeginLoc() const LLVM_READONLY { return AtFinallyLoc; }
0144   SourceLocation getEndLoc() const LLVM_READONLY {
0145     return AtFinallyStmt->getEndLoc();
0146   }
0147 
0148   SourceLocation getAtFinallyLoc() const { return AtFinallyLoc; }
0149   void setAtFinallyLoc(SourceLocation Loc) { AtFinallyLoc = Loc; }
0150 
0151   static bool classof(const Stmt *T) {
0152     return T->getStmtClass() == ObjCAtFinallyStmtClass;
0153   }
0154 
0155   child_range children() {
0156     return child_range(&AtFinallyStmt, &AtFinallyStmt+1);
0157   }
0158 
0159   const_child_range children() const {
0160     return const_child_range(&AtFinallyStmt, &AtFinallyStmt + 1);
0161   }
0162 };
0163 
0164 /// Represents Objective-C's \@try ... \@catch ... \@finally statement.
0165 class ObjCAtTryStmt final
0166     : public Stmt,
0167       private llvm::TrailingObjects<ObjCAtTryStmt, Stmt *> {
0168   friend TrailingObjects;
0169   size_t numTrailingObjects(OverloadToken<Stmt *>) const {
0170     return 1 + NumCatchStmts + HasFinally;
0171   }
0172 
0173   // The location of the @ in the \@try.
0174   SourceLocation AtTryLoc;
0175 
0176   // The number of catch blocks in this statement.
0177   unsigned NumCatchStmts : 16;
0178 
0179   // Whether this statement has a \@finally statement.
0180   LLVM_PREFERRED_TYPE(bool)
0181   unsigned HasFinally : 1;
0182 
0183   /// Retrieve the statements that are stored after this \@try statement.
0184   ///
0185   /// The order of the statements in memory follows the order in the source,
0186   /// with the \@try body first, followed by the \@catch statements (if any)
0187   /// and, finally, the \@finally (if it exists).
0188   Stmt **getStmts() { return getTrailingObjects<Stmt *>(); }
0189   Stmt *const *getStmts() const { return getTrailingObjects<Stmt *>(); }
0190 
0191   ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
0192                 Stmt **CatchStmts, unsigned NumCatchStmts,
0193                 Stmt *atFinallyStmt);
0194 
0195   explicit ObjCAtTryStmt(EmptyShell Empty, unsigned NumCatchStmts,
0196                          bool HasFinally)
0197     : Stmt(ObjCAtTryStmtClass, Empty), NumCatchStmts(NumCatchStmts),
0198       HasFinally(HasFinally) { }
0199 
0200 public:
0201   static ObjCAtTryStmt *Create(const ASTContext &Context,
0202                                SourceLocation atTryLoc, Stmt *atTryStmt,
0203                                Stmt **CatchStmts, unsigned NumCatchStmts,
0204                                Stmt *atFinallyStmt);
0205   static ObjCAtTryStmt *CreateEmpty(const ASTContext &Context,
0206                                     unsigned NumCatchStmts, bool HasFinally);
0207 
0208   /// Retrieve the location of the @ in the \@try.
0209   SourceLocation getAtTryLoc() const { return AtTryLoc; }
0210   void setAtTryLoc(SourceLocation Loc) { AtTryLoc = Loc; }
0211 
0212   /// Retrieve the \@try body.
0213   const Stmt *getTryBody() const { return getStmts()[0]; }
0214   Stmt *getTryBody() { return getStmts()[0]; }
0215   void setTryBody(Stmt *S) { getStmts()[0] = S; }
0216 
0217   /// Retrieve the number of \@catch statements in this try-catch-finally
0218   /// block.
0219   unsigned getNumCatchStmts() const { return NumCatchStmts; }
0220 
0221   /// Retrieve a \@catch statement.
0222   const ObjCAtCatchStmt *getCatchStmt(unsigned I) const {
0223     assert(I < NumCatchStmts && "Out-of-bounds @catch index");
0224     return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
0225   }
0226 
0227   /// Retrieve a \@catch statement.
0228   ObjCAtCatchStmt *getCatchStmt(unsigned I) {
0229     assert(I < NumCatchStmts && "Out-of-bounds @catch index");
0230     return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
0231   }
0232 
0233   /// Set a particular catch statement.
0234   void setCatchStmt(unsigned I, ObjCAtCatchStmt *S) {
0235     assert(I < NumCatchStmts && "Out-of-bounds @catch index");
0236     getStmts()[I + 1] = S;
0237   }
0238 
0239   /// Retrieve the \@finally statement, if any.
0240   const ObjCAtFinallyStmt *getFinallyStmt() const {
0241     if (!HasFinally)
0242       return nullptr;
0243 
0244     return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
0245   }
0246   ObjCAtFinallyStmt *getFinallyStmt() {
0247     if (!HasFinally)
0248       return nullptr;
0249 
0250     return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
0251   }
0252   void setFinallyStmt(Stmt *S) {
0253     assert(HasFinally && "@try does not have a @finally slot!");
0254     getStmts()[1 + NumCatchStmts] = S;
0255   }
0256 
0257   SourceLocation getBeginLoc() const LLVM_READONLY { return AtTryLoc; }
0258   SourceLocation getEndLoc() const LLVM_READONLY;
0259 
0260   static bool classof(const Stmt *T) {
0261     return T->getStmtClass() == ObjCAtTryStmtClass;
0262   }
0263 
0264   child_range children() {
0265     return child_range(
0266         getStmts(), getStmts() + numTrailingObjects(OverloadToken<Stmt *>()));
0267   }
0268 
0269   const_child_range children() const {
0270     return const_child_range(const_cast<ObjCAtTryStmt *>(this)->children());
0271   }
0272 
0273   using catch_stmt_iterator = CastIterator<ObjCAtCatchStmt>;
0274   using const_catch_stmt_iterator = ConstCastIterator<ObjCAtCatchStmt>;
0275   using catch_range = llvm::iterator_range<catch_stmt_iterator>;
0276   using catch_const_range = llvm::iterator_range<const_catch_stmt_iterator>;
0277 
0278   catch_stmt_iterator catch_stmts_begin() { return getStmts() + 1; }
0279   catch_stmt_iterator catch_stmts_end() {
0280     return catch_stmts_begin() + NumCatchStmts;
0281   }
0282   catch_range catch_stmts() {
0283     return catch_range(catch_stmts_begin(), catch_stmts_end());
0284   }
0285 
0286   const_catch_stmt_iterator catch_stmts_begin() const { return getStmts() + 1; }
0287   const_catch_stmt_iterator catch_stmts_end() const {
0288     return catch_stmts_begin() + NumCatchStmts;
0289   }
0290   catch_const_range catch_stmts() const {
0291     return catch_const_range(catch_stmts_begin(), catch_stmts_end());
0292   }
0293 };
0294 
0295 /// Represents Objective-C's \@synchronized statement.
0296 ///
0297 /// Example:
0298 /// \code
0299 ///   @synchronized (sem) {
0300 ///     do-something;
0301 ///   }
0302 /// \endcode
0303 class ObjCAtSynchronizedStmt : public Stmt {
0304 private:
0305   SourceLocation AtSynchronizedLoc;
0306   enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
0307   Stmt* SubStmts[END_EXPR];
0308 
0309 public:
0310   ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
0311                          Stmt *synchBody)
0312   : Stmt(ObjCAtSynchronizedStmtClass) {
0313     SubStmts[SYNC_EXPR] = synchExpr;
0314     SubStmts[SYNC_BODY] = synchBody;
0315     AtSynchronizedLoc = atSynchronizedLoc;
0316   }
0317   explicit ObjCAtSynchronizedStmt(EmptyShell Empty) :
0318     Stmt(ObjCAtSynchronizedStmtClass, Empty) { }
0319 
0320   SourceLocation getAtSynchronizedLoc() const { return AtSynchronizedLoc; }
0321   void setAtSynchronizedLoc(SourceLocation Loc) { AtSynchronizedLoc = Loc; }
0322 
0323   const CompoundStmt *getSynchBody() const {
0324     return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
0325   }
0326   CompoundStmt *getSynchBody() {
0327     return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
0328   }
0329   void setSynchBody(Stmt *S) { SubStmts[SYNC_BODY] = S; }
0330 
0331   const Expr *getSynchExpr() const {
0332     return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
0333   }
0334   Expr *getSynchExpr() {
0335     return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
0336   }
0337   void setSynchExpr(Stmt *S) { SubStmts[SYNC_EXPR] = S; }
0338 
0339   SourceLocation getBeginLoc() const LLVM_READONLY { return AtSynchronizedLoc; }
0340   SourceLocation getEndLoc() const LLVM_READONLY {
0341     return getSynchBody()->getEndLoc();
0342   }
0343 
0344   static bool classof(const Stmt *T) {
0345     return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
0346   }
0347 
0348   child_range children() {
0349     return child_range(&SubStmts[0], &SubStmts[0]+END_EXPR);
0350   }
0351 
0352   const_child_range children() const {
0353     return const_child_range(&SubStmts[0], &SubStmts[0] + END_EXPR);
0354   }
0355 };
0356 
0357 /// Represents Objective-C's \@throw statement.
0358 class ObjCAtThrowStmt : public Stmt {
0359   SourceLocation AtThrowLoc;
0360   Stmt *Throw;
0361 
0362 public:
0363   ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
0364   : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) {
0365     AtThrowLoc = atThrowLoc;
0366   }
0367   explicit ObjCAtThrowStmt(EmptyShell Empty) :
0368     Stmt(ObjCAtThrowStmtClass, Empty) { }
0369 
0370   const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
0371   Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); }
0372   void setThrowExpr(Stmt *S) { Throw = S; }
0373 
0374   SourceLocation getThrowLoc() const LLVM_READONLY { return AtThrowLoc; }
0375   void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; }
0376 
0377   SourceLocation getBeginLoc() const LLVM_READONLY { return AtThrowLoc; }
0378   SourceLocation getEndLoc() const LLVM_READONLY {
0379     return Throw ? Throw->getEndLoc() : AtThrowLoc;
0380   }
0381 
0382   static bool classof(const Stmt *T) {
0383     return T->getStmtClass() == ObjCAtThrowStmtClass;
0384   }
0385 
0386   child_range children() { return child_range(&Throw, &Throw+1); }
0387 
0388   const_child_range children() const {
0389     return const_child_range(&Throw, &Throw + 1);
0390   }
0391 };
0392 
0393 /// Represents Objective-C's \@autoreleasepool Statement
0394 class ObjCAutoreleasePoolStmt : public Stmt {
0395   SourceLocation AtLoc;
0396   Stmt *SubStmt;
0397 
0398 public:
0399   ObjCAutoreleasePoolStmt(SourceLocation atLoc, Stmt *subStmt)
0400       : Stmt(ObjCAutoreleasePoolStmtClass), AtLoc(atLoc), SubStmt(subStmt) {}
0401 
0402   explicit ObjCAutoreleasePoolStmt(EmptyShell Empty) :
0403     Stmt(ObjCAutoreleasePoolStmtClass, Empty) { }
0404 
0405   const Stmt *getSubStmt() const { return SubStmt; }
0406   Stmt *getSubStmt() { return SubStmt; }
0407   void setSubStmt(Stmt *S) { SubStmt = S; }
0408 
0409   SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
0410   SourceLocation getEndLoc() const LLVM_READONLY {
0411     return SubStmt->getEndLoc();
0412   }
0413 
0414   SourceLocation getAtLoc() const { return AtLoc; }
0415   void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
0416 
0417   static bool classof(const Stmt *T) {
0418     return T->getStmtClass() == ObjCAutoreleasePoolStmtClass;
0419   }
0420 
0421   child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
0422 
0423   const_child_range children() const {
0424     return const_child_range(&SubStmt, &SubStmt + 1);
0425   }
0426 };
0427 
0428 }  // end namespace clang
0429 
0430 #endif