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