Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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