StmtObjC.h 14 KB

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