Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //===--- StmtCXX.h - Classes for representing C++ 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. // This file defines the C++ statement AST node classes.
  10. //
  11. //===----------------------------------------------------------------------===//
  12.  
  13. #ifndef LLVM_CLANG_AST_STMTCXX_H
  14. #define LLVM_CLANG_AST_STMTCXX_H
  15.  
  16. #include "clang/AST/DeclarationName.h"
  17. #include "clang/AST/Expr.h"
  18. #include "clang/AST/NestedNameSpecifier.h"
  19. #include "clang/AST/Stmt.h"
  20. #include "llvm/Support/Compiler.h"
  21.  
  22. namespace clang {
  23.  
  24. class VarDecl;
  25.  
  26. /// CXXCatchStmt - This represents a C++ catch block.
  27. ///
  28. class CXXCatchStmt : public Stmt {
  29.   SourceLocation CatchLoc;
  30.   /// The exception-declaration of the type.
  31.   VarDecl *ExceptionDecl;
  32.   /// The handler block.
  33.   Stmt *HandlerBlock;
  34.  
  35. public:
  36.   CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock)
  37.   : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
  38.     HandlerBlock(handlerBlock) {}
  39.  
  40.   CXXCatchStmt(EmptyShell Empty)
  41.   : Stmt(CXXCatchStmtClass), ExceptionDecl(nullptr), HandlerBlock(nullptr) {}
  42.  
  43.   SourceLocation getBeginLoc() const LLVM_READONLY { return CatchLoc; }
  44.   SourceLocation getEndLoc() const LLVM_READONLY {
  45.     return HandlerBlock->getEndLoc();
  46.   }
  47.  
  48.   SourceLocation getCatchLoc() const { return CatchLoc; }
  49.   VarDecl *getExceptionDecl() const { return ExceptionDecl; }
  50.   QualType getCaughtType() const;
  51.   Stmt *getHandlerBlock() const { return HandlerBlock; }
  52.  
  53.   static bool classof(const Stmt *T) {
  54.     return T->getStmtClass() == CXXCatchStmtClass;
  55.   }
  56.  
  57.   child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); }
  58.  
  59.   const_child_range children() const {
  60.     return const_child_range(&HandlerBlock, &HandlerBlock + 1);
  61.   }
  62.  
  63.   friend class ASTStmtReader;
  64. };
  65.  
  66. /// CXXTryStmt - A C++ try block, including all handlers.
  67. ///
  68. class CXXTryStmt final : public Stmt,
  69.                          private llvm::TrailingObjects<CXXTryStmt, Stmt *> {
  70.  
  71.   friend TrailingObjects;
  72.   friend class ASTStmtReader;
  73.  
  74.   SourceLocation TryLoc;
  75.   unsigned NumHandlers;
  76.   size_t numTrailingObjects(OverloadToken<Stmt *>) const { return NumHandlers; }
  77.  
  78.   CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, ArrayRef<Stmt*> handlers);
  79.   CXXTryStmt(EmptyShell Empty, unsigned numHandlers)
  80.     : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { }
  81.  
  82.   Stmt *const *getStmts() const { return getTrailingObjects<Stmt *>(); }
  83.   Stmt **getStmts() { return getTrailingObjects<Stmt *>(); }
  84.  
  85. public:
  86.   static CXXTryStmt *Create(const ASTContext &C, SourceLocation tryLoc,
  87.                             Stmt *tryBlock, ArrayRef<Stmt*> handlers);
  88.  
  89.   static CXXTryStmt *Create(const ASTContext &C, EmptyShell Empty,
  90.                             unsigned numHandlers);
  91.  
  92.   SourceLocation getBeginLoc() const LLVM_READONLY { return getTryLoc(); }
  93.  
  94.   SourceLocation getTryLoc() const { return TryLoc; }
  95.   SourceLocation getEndLoc() const {
  96.     return getStmts()[NumHandlers]->getEndLoc();
  97.   }
  98.  
  99.   CompoundStmt *getTryBlock() {
  100.     return cast<CompoundStmt>(getStmts()[0]);
  101.   }
  102.   const CompoundStmt *getTryBlock() const {
  103.     return cast<CompoundStmt>(getStmts()[0]);
  104.   }
  105.  
  106.   unsigned getNumHandlers() const { return NumHandlers; }
  107.   CXXCatchStmt *getHandler(unsigned i) {
  108.     return cast<CXXCatchStmt>(getStmts()[i + 1]);
  109.   }
  110.   const CXXCatchStmt *getHandler(unsigned i) const {
  111.     return cast<CXXCatchStmt>(getStmts()[i + 1]);
  112.   }
  113.  
  114.   static bool classof(const Stmt *T) {
  115.     return T->getStmtClass() == CXXTryStmtClass;
  116.   }
  117.  
  118.   child_range children() {
  119.     return child_range(getStmts(), getStmts() + getNumHandlers() + 1);
  120.   }
  121.  
  122.   const_child_range children() const {
  123.     return const_child_range(getStmts(), getStmts() + getNumHandlers() + 1);
  124.   }
  125. };
  126.  
  127. /// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for
  128. /// statement, represented as 'for (range-declarator : range-expression)'
  129. /// or 'for (init-statement range-declarator : range-expression)'.
  130. ///
  131. /// This is stored in a partially-desugared form to allow full semantic
  132. /// analysis of the constituent components. The original syntactic components
  133. /// can be extracted using getLoopVariable and getRangeInit.
  134. class CXXForRangeStmt : public Stmt {
  135.   SourceLocation ForLoc;
  136.   enum { INIT, RANGE, BEGINSTMT, ENDSTMT, COND, INC, LOOPVAR, BODY, END };
  137.   // SubExprs[RANGE] is an expression or declstmt.
  138.   // SubExprs[COND] and SubExprs[INC] are expressions.
  139.   Stmt *SubExprs[END];
  140.   SourceLocation CoawaitLoc;
  141.   SourceLocation ColonLoc;
  142.   SourceLocation RParenLoc;
  143.  
  144.   friend class ASTStmtReader;
  145. public:
  146.   CXXForRangeStmt(Stmt *InitStmt, DeclStmt *Range, DeclStmt *Begin,
  147.                   DeclStmt *End, Expr *Cond, Expr *Inc, DeclStmt *LoopVar,
  148.                   Stmt *Body, SourceLocation FL, SourceLocation CAL,
  149.                   SourceLocation CL, SourceLocation RPL);
  150.   CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { }
  151.  
  152.   Stmt *getInit() { return SubExprs[INIT]; }
  153.   VarDecl *getLoopVariable();
  154.   Expr *getRangeInit();
  155.  
  156.   const Stmt *getInit() const { return SubExprs[INIT]; }
  157.   const VarDecl *getLoopVariable() const;
  158.   const Expr *getRangeInit() const;
  159.  
  160.  
  161.   DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); }
  162.   DeclStmt *getBeginStmt() {
  163.     return cast_or_null<DeclStmt>(SubExprs[BEGINSTMT]);
  164.   }
  165.   DeclStmt *getEndStmt() { return cast_or_null<DeclStmt>(SubExprs[ENDSTMT]); }
  166.   Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); }
  167.   Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); }
  168.   DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); }
  169.   Stmt *getBody() { return SubExprs[BODY]; }
  170.  
  171.   const DeclStmt *getRangeStmt() const {
  172.     return cast<DeclStmt>(SubExprs[RANGE]);
  173.   }
  174.   const DeclStmt *getBeginStmt() const {
  175.     return cast_or_null<DeclStmt>(SubExprs[BEGINSTMT]);
  176.   }
  177.   const DeclStmt *getEndStmt() const {
  178.     return cast_or_null<DeclStmt>(SubExprs[ENDSTMT]);
  179.   }
  180.   const Expr *getCond() const {
  181.     return cast_or_null<Expr>(SubExprs[COND]);
  182.   }
  183.   const Expr *getInc() const {
  184.     return cast_or_null<Expr>(SubExprs[INC]);
  185.   }
  186.   const DeclStmt *getLoopVarStmt() const {
  187.     return cast<DeclStmt>(SubExprs[LOOPVAR]);
  188.   }
  189.   const Stmt *getBody() const { return SubExprs[BODY]; }
  190.  
  191.   void setInit(Stmt *S) { SubExprs[INIT] = S; }
  192.   void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); }
  193.   void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; }
  194.   void setBeginStmt(Stmt *S) { SubExprs[BEGINSTMT] = S; }
  195.   void setEndStmt(Stmt *S) { SubExprs[ENDSTMT] = S; }
  196.   void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
  197.   void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
  198.   void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; }
  199.   void setBody(Stmt *S) { SubExprs[BODY] = S; }
  200.  
  201.   SourceLocation getForLoc() const { return ForLoc; }
  202.   SourceLocation getCoawaitLoc() const { return CoawaitLoc; }
  203.   SourceLocation getColonLoc() const { return ColonLoc; }
  204.   SourceLocation getRParenLoc() const { return RParenLoc; }
  205.  
  206.   SourceLocation getBeginLoc() const LLVM_READONLY { return ForLoc; }
  207.   SourceLocation getEndLoc() const LLVM_READONLY {
  208.     return SubExprs[BODY]->getEndLoc();
  209.   }
  210.  
  211.   static bool classof(const Stmt *T) {
  212.     return T->getStmtClass() == CXXForRangeStmtClass;
  213.   }
  214.  
  215.   // Iterators
  216.   child_range children() {
  217.     return child_range(&SubExprs[0], &SubExprs[END]);
  218.   }
  219.  
  220.   const_child_range children() const {
  221.     return const_child_range(&SubExprs[0], &SubExprs[END]);
  222.   }
  223. };
  224.  
  225. /// Representation of a Microsoft __if_exists or __if_not_exists
  226. /// statement with a dependent name.
  227. ///
  228. /// The __if_exists statement can be used to include a sequence of statements
  229. /// in the program only when a particular dependent name does not exist. For
  230. /// example:
  231. ///
  232. /// \code
  233. /// template<typename T>
  234. /// void call_foo(T &t) {
  235. ///   __if_exists (T::foo) {
  236. ///     t.foo(); // okay: only called when T::foo exists.
  237. ///   }
  238. /// }
  239. /// \endcode
  240. ///
  241. /// Similarly, the __if_not_exists statement can be used to include the
  242. /// statements when a particular name does not exist.
  243. ///
  244. /// Note that this statement only captures __if_exists and __if_not_exists
  245. /// statements whose name is dependent. All non-dependent cases are handled
  246. /// directly in the parser, so that they don't introduce a new scope. Clang
  247. /// introduces scopes in the dependent case to keep names inside the compound
  248. /// statement from leaking out into the surround statements, which would
  249. /// compromise the template instantiation model. This behavior differs from
  250. /// Visual C++ (which never introduces a scope), but is a fairly reasonable
  251. /// approximation of the VC++ behavior.
  252. class MSDependentExistsStmt : public Stmt {
  253.   SourceLocation KeywordLoc;
  254.   bool IsIfExists;
  255.   NestedNameSpecifierLoc QualifierLoc;
  256.   DeclarationNameInfo NameInfo;
  257.   Stmt *SubStmt;
  258.  
  259.   friend class ASTReader;
  260.   friend class ASTStmtReader;
  261.  
  262. public:
  263.   MSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists,
  264.                         NestedNameSpecifierLoc QualifierLoc,
  265.                         DeclarationNameInfo NameInfo,
  266.                         CompoundStmt *SubStmt)
  267.   : Stmt(MSDependentExistsStmtClass),
  268.     KeywordLoc(KeywordLoc), IsIfExists(IsIfExists),
  269.     QualifierLoc(QualifierLoc), NameInfo(NameInfo),
  270.     SubStmt(reinterpret_cast<Stmt *>(SubStmt)) { }
  271.  
  272.   /// Retrieve the location of the __if_exists or __if_not_exists
  273.   /// keyword.
  274.   SourceLocation getKeywordLoc() const { return KeywordLoc; }
  275.  
  276.   /// Determine whether this is an __if_exists statement.
  277.   bool isIfExists() const { return IsIfExists; }
  278.  
  279.   /// Determine whether this is an __if_exists statement.
  280.   bool isIfNotExists() const { return !IsIfExists; }
  281.  
  282.   /// Retrieve the nested-name-specifier that qualifies this name, if
  283.   /// any.
  284.   NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
  285.  
  286.   /// Retrieve the name of the entity we're testing for, along with
  287.   /// location information
  288.   DeclarationNameInfo getNameInfo() const { return NameInfo; }
  289.  
  290.   /// Retrieve the compound statement that will be included in the
  291.   /// program only if the existence of the symbol matches the initial keyword.
  292.   CompoundStmt *getSubStmt() const {
  293.     return reinterpret_cast<CompoundStmt *>(SubStmt);
  294.   }
  295.  
  296.   SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; }
  297.   SourceLocation getEndLoc() const LLVM_READONLY {
  298.     return SubStmt->getEndLoc();
  299.   }
  300.  
  301.   child_range children() {
  302.     return child_range(&SubStmt, &SubStmt+1);
  303.   }
  304.  
  305.   const_child_range children() const {
  306.     return const_child_range(&SubStmt, &SubStmt + 1);
  307.   }
  308.  
  309.   static bool classof(const Stmt *T) {
  310.     return T->getStmtClass() == MSDependentExistsStmtClass;
  311.   }
  312. };
  313.  
  314. /// Represents the body of a coroutine. This wraps the normal function
  315. /// body and holds the additional semantic context required to set up and tear
  316. /// down the coroutine frame.
  317. class CoroutineBodyStmt final
  318.     : public Stmt,
  319.       private llvm::TrailingObjects<CoroutineBodyStmt, Stmt *> {
  320.   enum SubStmt {
  321.     Body,          ///< The body of the coroutine.
  322.     Promise,       ///< The promise statement.
  323.     InitSuspend,   ///< The initial suspend statement, run before the body.
  324.     FinalSuspend,  ///< The final suspend statement, run after the body.
  325.     OnException,   ///< Handler for exceptions thrown in the body.
  326.     OnFallthrough, ///< Handler for control flow falling off the body.
  327.     Allocate,      ///< Coroutine frame memory allocation.
  328.     Deallocate,    ///< Coroutine frame memory deallocation.
  329.     ReturnValue,   ///< Return value for thunk function: p.get_return_object().
  330.     ReturnStmt,    ///< Return statement for the thunk function.
  331.     ReturnStmtOnAllocFailure, ///< Return statement if allocation failed.
  332.     FirstParamMove ///< First offset for move construction of parameter copies.
  333.   };
  334.   unsigned NumParams;
  335.  
  336.   friend class ASTStmtReader;
  337.   friend class ASTReader;
  338.   friend TrailingObjects;
  339.  
  340.   Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); }
  341.  
  342.   Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
  343.  
  344. public:
  345.  
  346.   struct CtorArgs {
  347.     Stmt *Body = nullptr;
  348.     Stmt *Promise = nullptr;
  349.     Expr *InitialSuspend = nullptr;
  350.     Expr *FinalSuspend = nullptr;
  351.     Stmt *OnException = nullptr;
  352.     Stmt *OnFallthrough = nullptr;
  353.     Expr *Allocate = nullptr;
  354.     Expr *Deallocate = nullptr;
  355.     Expr *ReturnValue = nullptr;
  356.     Stmt *ReturnStmt = nullptr;
  357.     Stmt *ReturnStmtOnAllocFailure = nullptr;
  358.     ArrayRef<Stmt *> ParamMoves;
  359.   };
  360.  
  361. private:
  362.  
  363.   CoroutineBodyStmt(CtorArgs const& Args);
  364.  
  365. public:
  366.   static CoroutineBodyStmt *Create(const ASTContext &C, CtorArgs const &Args);
  367.   static CoroutineBodyStmt *Create(const ASTContext &C, EmptyShell,
  368.                                    unsigned NumParams);
  369.  
  370.   bool hasDependentPromiseType() const {
  371.     return getPromiseDecl()->getType()->isDependentType();
  372.   }
  373.  
  374.   /// Retrieve the body of the coroutine as written. This will be either
  375.   /// a CompoundStmt or a TryStmt.
  376.   Stmt *getBody() const {
  377.     return getStoredStmts()[SubStmt::Body];
  378.   }
  379.  
  380.   Stmt *getPromiseDeclStmt() const {
  381.     return getStoredStmts()[SubStmt::Promise];
  382.   }
  383.   VarDecl *getPromiseDecl() const {
  384.     return cast<VarDecl>(cast<DeclStmt>(getPromiseDeclStmt())->getSingleDecl());
  385.   }
  386.  
  387.   Stmt *getInitSuspendStmt() const {
  388.     return getStoredStmts()[SubStmt::InitSuspend];
  389.   }
  390.   Stmt *getFinalSuspendStmt() const {
  391.     return getStoredStmts()[SubStmt::FinalSuspend];
  392.   }
  393.  
  394.   Stmt *getExceptionHandler() const {
  395.     return getStoredStmts()[SubStmt::OnException];
  396.   }
  397.   Stmt *getFallthroughHandler() const {
  398.     return getStoredStmts()[SubStmt::OnFallthrough];
  399.   }
  400.  
  401.   Expr *getAllocate() const {
  402.     return cast_or_null<Expr>(getStoredStmts()[SubStmt::Allocate]);
  403.   }
  404.   Expr *getDeallocate() const {
  405.     return cast_or_null<Expr>(getStoredStmts()[SubStmt::Deallocate]);
  406.   }
  407.   Expr *getReturnValueInit() const {
  408.     return cast<Expr>(getStoredStmts()[SubStmt::ReturnValue]);
  409.   }
  410.   Expr *getReturnValue() const {
  411.     assert(getReturnStmt());
  412.     auto *RS = cast<clang::ReturnStmt>(getReturnStmt());
  413.     return RS->getRetValue();
  414.   }
  415.   Stmt *getReturnStmt() const { return getStoredStmts()[SubStmt::ReturnStmt]; }
  416.   Stmt *getReturnStmtOnAllocFailure() const {
  417.     return getStoredStmts()[SubStmt::ReturnStmtOnAllocFailure];
  418.   }
  419.   ArrayRef<Stmt const *> getParamMoves() const {
  420.     return {getStoredStmts() + SubStmt::FirstParamMove, NumParams};
  421.   }
  422.  
  423.   SourceLocation getBeginLoc() const LLVM_READONLY {
  424.     return getBody() ? getBody()->getBeginLoc()
  425.                      : getPromiseDecl()->getBeginLoc();
  426.   }
  427.   SourceLocation getEndLoc() const LLVM_READONLY {
  428.     return getBody() ? getBody()->getEndLoc() : getPromiseDecl()->getEndLoc();
  429.   }
  430.  
  431.   child_range children() {
  432.     return child_range(getStoredStmts(),
  433.                        getStoredStmts() + SubStmt::FirstParamMove + NumParams);
  434.   }
  435.  
  436.   const_child_range children() const {
  437.     return const_child_range(getStoredStmts(), getStoredStmts() +
  438.                                                    SubStmt::FirstParamMove +
  439.                                                    NumParams);
  440.   }
  441.  
  442.   static bool classof(const Stmt *T) {
  443.     return T->getStmtClass() == CoroutineBodyStmtClass;
  444.   }
  445. };
  446.  
  447. /// Represents a 'co_return' statement in the C++ Coroutines TS.
  448. ///
  449. /// This statament models the initialization of the coroutine promise
  450. /// (encapsulating the eventual notional return value) from an expression
  451. /// (or braced-init-list), followed by termination of the coroutine.
  452. ///
  453. /// This initialization is modeled by the evaluation of the operand
  454. /// followed by a call to one of:
  455. ///   <promise>.return_value(<operand>)
  456. ///   <promise>.return_void()
  457. /// which we name the "promise call".
  458. class CoreturnStmt : public Stmt {
  459.   SourceLocation CoreturnLoc;
  460.  
  461.   enum SubStmt { Operand, PromiseCall, Count };
  462.   Stmt *SubStmts[SubStmt::Count];
  463.  
  464.   bool IsImplicit : 1;
  465.  
  466.   friend class ASTStmtReader;
  467. public:
  468.   CoreturnStmt(SourceLocation CoreturnLoc, Stmt *Operand, Stmt *PromiseCall,
  469.                bool IsImplicit = false)
  470.       : Stmt(CoreturnStmtClass), CoreturnLoc(CoreturnLoc),
  471.         IsImplicit(IsImplicit) {
  472.     SubStmts[SubStmt::Operand] = Operand;
  473.     SubStmts[SubStmt::PromiseCall] = PromiseCall;
  474.   }
  475.  
  476.   CoreturnStmt(EmptyShell) : CoreturnStmt({}, {}, {}) {}
  477.  
  478.   SourceLocation getKeywordLoc() const { return CoreturnLoc; }
  479.  
  480.   /// Retrieve the operand of the 'co_return' statement. Will be nullptr
  481.   /// if none was specified.
  482.   Expr *getOperand() const { return static_cast<Expr*>(SubStmts[Operand]); }
  483.  
  484.   /// Retrieve the promise call that results from this 'co_return'
  485.   /// statement. Will be nullptr if either the coroutine has not yet been
  486.   /// finalized or the coroutine has no eventual return type.
  487.   Expr *getPromiseCall() const {
  488.     return static_cast<Expr*>(SubStmts[PromiseCall]);
  489.   }
  490.  
  491.   bool isImplicit() const { return IsImplicit; }
  492.   void setIsImplicit(bool value = true) { IsImplicit = value; }
  493.  
  494.   SourceLocation getBeginLoc() const LLVM_READONLY { return CoreturnLoc; }
  495.   SourceLocation getEndLoc() const LLVM_READONLY {
  496.     return getOperand() ? getOperand()->getEndLoc() : getBeginLoc();
  497.   }
  498.  
  499.   child_range children() {
  500.     return child_range(SubStmts, SubStmts + SubStmt::Count);
  501.   }
  502.  
  503.   const_child_range children() const {
  504.     return const_child_range(SubStmts, SubStmts + SubStmt::Count);
  505.   }
  506.  
  507.   static bool classof(const Stmt *T) {
  508.     return T->getStmtClass() == CoreturnStmtClass;
  509.   }
  510. };
  511.  
  512. }  // end namespace clang
  513.  
  514. #endif
  515.