Home | History | Annotate | Download | only in AST
      1 //===--- StmtCXX.h - Classes for representing C++ statements ----*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines the C++ statement AST node classes.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_CLANG_AST_STMTCXX_H
     15 #define LLVM_CLANG_AST_STMTCXX_H
     16 
     17 #include "clang/AST/Stmt.h"
     18 
     19 namespace clang {
     20 
     21 class VarDecl;
     22 
     23 /// CXXCatchStmt - This represents a C++ catch block.
     24 ///
     25 class CXXCatchStmt : public Stmt {
     26   SourceLocation CatchLoc;
     27   /// The exception-declaration of the type.
     28   VarDecl *ExceptionDecl;
     29   /// The handler block.
     30   Stmt *HandlerBlock;
     31 
     32 public:
     33   CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock)
     34   : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
     35     HandlerBlock(handlerBlock) {}
     36 
     37   CXXCatchStmt(EmptyShell Empty)
     38   : Stmt(CXXCatchStmtClass), ExceptionDecl(0), HandlerBlock(0) {}
     39 
     40   SourceRange getSourceRange() const {
     41     return SourceRange(CatchLoc, HandlerBlock->getLocEnd());
     42   }
     43 
     44   SourceLocation getCatchLoc() const { return CatchLoc; }
     45   VarDecl *getExceptionDecl() const { return ExceptionDecl; }
     46   QualType getCaughtType() const;
     47   Stmt *getHandlerBlock() const { return HandlerBlock; }
     48 
     49   static bool classof(const Stmt *T) {
     50     return T->getStmtClass() == CXXCatchStmtClass;
     51   }
     52   static bool classof(const CXXCatchStmt *) { return true; }
     53 
     54   child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); }
     55 
     56   friend class ASTStmtReader;
     57 };
     58 
     59 /// CXXTryStmt - A C++ try block, including all handlers.
     60 ///
     61 class CXXTryStmt : public Stmt {
     62   SourceLocation TryLoc;
     63   unsigned NumHandlers;
     64 
     65   CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, Stmt **handlers,
     66              unsigned numHandlers);
     67 
     68   CXXTryStmt(EmptyShell Empty, unsigned numHandlers)
     69     : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { }
     70 
     71   Stmt const * const *getStmts() const {
     72     return reinterpret_cast<Stmt const * const*>(this + 1);
     73   }
     74   Stmt **getStmts() {
     75     return reinterpret_cast<Stmt **>(this + 1);
     76   }
     77 
     78 public:
     79   static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc,
     80                             Stmt *tryBlock, Stmt **handlers,
     81                             unsigned numHandlers);
     82 
     83   static CXXTryStmt *Create(ASTContext &C, EmptyShell Empty,
     84                             unsigned numHandlers);
     85 
     86   SourceRange getSourceRange() const {
     87     return SourceRange(getTryLoc(), getEndLoc());
     88   }
     89 
     90   SourceLocation getTryLoc() const { return TryLoc; }
     91   SourceLocation getEndLoc() const {
     92     return getStmts()[NumHandlers]->getLocEnd();
     93   }
     94 
     95   CompoundStmt *getTryBlock() {
     96     return llvm::cast<CompoundStmt>(getStmts()[0]);
     97   }
     98   const CompoundStmt *getTryBlock() const {
     99     return llvm::cast<CompoundStmt>(getStmts()[0]);
    100   }
    101 
    102   unsigned getNumHandlers() const { return NumHandlers; }
    103   CXXCatchStmt *getHandler(unsigned i) {
    104     return llvm::cast<CXXCatchStmt>(getStmts()[i + 1]);
    105   }
    106   const CXXCatchStmt *getHandler(unsigned i) const {
    107     return llvm::cast<CXXCatchStmt>(getStmts()[i + 1]);
    108   }
    109 
    110   static bool classof(const Stmt *T) {
    111     return T->getStmtClass() == CXXTryStmtClass;
    112   }
    113   static bool classof(const CXXTryStmt *) { return true; }
    114 
    115   child_range children() {
    116     return child_range(getStmts(), getStmts() + getNumHandlers() + 1);
    117   }
    118 
    119   friend class ASTStmtReader;
    120 };
    121 
    122 /// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for
    123 /// statement, represented as 'for (range-declarator : range-expression)'.
    124 ///
    125 /// This is stored in a partially-desugared form to allow full semantic
    126 /// analysis of the constituent components. The original syntactic components
    127 /// can be extracted using getLoopVariable and getRangeInit.
    128 class CXXForRangeStmt : public Stmt {
    129   enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END };
    130   // SubExprs[RANGE] is an expression or declstmt.
    131   // SubExprs[COND] and SubExprs[INC] are expressions.
    132   Stmt *SubExprs[END];
    133   SourceLocation ForLoc;
    134   SourceLocation ColonLoc;
    135   SourceLocation RParenLoc;
    136 public:
    137   CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd,
    138                   Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body,
    139                   SourceLocation FL, SourceLocation CL, SourceLocation RPL);
    140   CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { }
    141 
    142 
    143   VarDecl *getLoopVariable();
    144   Expr *getRangeInit();
    145 
    146   const VarDecl *getLoopVariable() const;
    147   const Expr *getRangeInit() const;
    148 
    149 
    150   DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); }
    151   DeclStmt *getBeginEndStmt() { return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); }
    152   Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); }
    153   Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); }
    154   DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); }
    155   Stmt *getBody() { return SubExprs[BODY]; }
    156 
    157   const DeclStmt *getRangeStmt() const {
    158     return cast<DeclStmt>(SubExprs[RANGE]);
    159   }
    160   const DeclStmt *getBeginEndStmt() const {
    161     return cast_or_null<DeclStmt>(SubExprs[BEGINEND]);
    162   }
    163   const Expr *getCond() const {
    164     return cast_or_null<Expr>(SubExprs[COND]);
    165   }
    166   const Expr *getInc() const {
    167     return cast_or_null<Expr>(SubExprs[INC]);
    168   }
    169   const DeclStmt *getLoopVarStmt() const {
    170     return cast<DeclStmt>(SubExprs[LOOPVAR]);
    171   }
    172   const Stmt *getBody() const { return SubExprs[BODY]; }
    173 
    174   void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); }
    175   void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; }
    176   void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; }
    177   void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
    178   void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
    179   void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; }
    180   void setBody(Stmt *S) { SubExprs[BODY] = S; }
    181 
    182 
    183   SourceLocation getForLoc() const { return ForLoc; }
    184   void setForLoc(SourceLocation Loc) { ForLoc = Loc; }
    185   SourceLocation getColonLoc() const { return ColonLoc; }
    186   void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
    187   SourceLocation getRParenLoc() const { return RParenLoc; }
    188   void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
    189 
    190   SourceRange getSourceRange() const {
    191     return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
    192   }
    193   static bool classof(const Stmt *T) {
    194     return T->getStmtClass() == CXXForRangeStmtClass;
    195   }
    196   static bool classof(const CXXForRangeStmt *) { return true; }
    197 
    198   // Iterators
    199   child_range children() {
    200     return child_range(&SubExprs[0], &SubExprs[END]);
    201   }
    202 };
    203 
    204 
    205 }  // end namespace clang
    206 
    207 #endif
    208