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: CXXCatchStmt(SourceLocation catchLoc,VarDecl * exDecl,Stmt * handlerBlock)33 CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock) 34 : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl), 35 HandlerBlock(handlerBlock) {} 36 CXXCatchStmt(EmptyShell Empty)37 CXXCatchStmt(EmptyShell Empty) 38 : Stmt(CXXCatchStmtClass), ExceptionDecl(0), HandlerBlock(0) {} 39 getSourceRange()40 SourceRange getSourceRange() const { 41 return SourceRange(CatchLoc, HandlerBlock->getLocEnd()); 42 } 43 getCatchLoc()44 SourceLocation getCatchLoc() const { return CatchLoc; } getExceptionDecl()45 VarDecl *getExceptionDecl() const { return ExceptionDecl; } 46 QualType getCaughtType() const; getHandlerBlock()47 Stmt *getHandlerBlock() const { return HandlerBlock; } 48 classof(const Stmt * T)49 static bool classof(const Stmt *T) { 50 return T->getStmtClass() == CXXCatchStmtClass; 51 } classof(const CXXCatchStmt *)52 static bool classof(const CXXCatchStmt *) { return true; } 53 children()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 CXXTryStmt(EmptyShell Empty,unsigned numHandlers)68 CXXTryStmt(EmptyShell Empty, unsigned numHandlers) 69 : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { } 70 getStmts()71 Stmt const * const *getStmts() const { 72 return reinterpret_cast<Stmt const * const*>(this + 1); 73 } getStmts()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 getSourceRange()86 SourceRange getSourceRange() const { 87 return SourceRange(getTryLoc(), getEndLoc()); 88 } 89 getTryLoc()90 SourceLocation getTryLoc() const { return TryLoc; } getEndLoc()91 SourceLocation getEndLoc() const { 92 return getStmts()[NumHandlers]->getLocEnd(); 93 } 94 getTryBlock()95 CompoundStmt *getTryBlock() { 96 return llvm::cast<CompoundStmt>(getStmts()[0]); 97 } getTryBlock()98 const CompoundStmt *getTryBlock() const { 99 return llvm::cast<CompoundStmt>(getStmts()[0]); 100 } 101 getNumHandlers()102 unsigned getNumHandlers() const { return NumHandlers; } getHandler(unsigned i)103 CXXCatchStmt *getHandler(unsigned i) { 104 return llvm::cast<CXXCatchStmt>(getStmts()[i + 1]); 105 } getHandler(unsigned i)106 const CXXCatchStmt *getHandler(unsigned i) const { 107 return llvm::cast<CXXCatchStmt>(getStmts()[i + 1]); 108 } 109 classof(const Stmt * T)110 static bool classof(const Stmt *T) { 111 return T->getStmtClass() == CXXTryStmtClass; 112 } classof(const CXXTryStmt *)113 static bool classof(const CXXTryStmt *) { return true; } 114 children()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); CXXForRangeStmt(EmptyShell Empty)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 getRangeStmt()150 DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); } getBeginEndStmt()151 DeclStmt *getBeginEndStmt() { return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); } getCond()152 Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); } getInc()153 Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); } getLoopVarStmt()154 DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); } getBody()155 Stmt *getBody() { return SubExprs[BODY]; } 156 getRangeStmt()157 const DeclStmt *getRangeStmt() const { 158 return cast<DeclStmt>(SubExprs[RANGE]); 159 } getBeginEndStmt()160 const DeclStmt *getBeginEndStmt() const { 161 return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); 162 } getCond()163 const Expr *getCond() const { 164 return cast_or_null<Expr>(SubExprs[COND]); 165 } getInc()166 const Expr *getInc() const { 167 return cast_or_null<Expr>(SubExprs[INC]); 168 } getLoopVarStmt()169 const DeclStmt *getLoopVarStmt() const { 170 return cast<DeclStmt>(SubExprs[LOOPVAR]); 171 } getBody()172 const Stmt *getBody() const { return SubExprs[BODY]; } 173 setRangeInit(Expr * E)174 void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); } setRangeStmt(Stmt * S)175 void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; } setBeginEndStmt(Stmt * S)176 void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; } setCond(Expr * E)177 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } setInc(Expr * E)178 void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); } setLoopVarStmt(Stmt * S)179 void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; } setBody(Stmt * S)180 void setBody(Stmt *S) { SubExprs[BODY] = S; } 181 182 getForLoc()183 SourceLocation getForLoc() const { return ForLoc; } setForLoc(SourceLocation Loc)184 void setForLoc(SourceLocation Loc) { ForLoc = Loc; } getColonLoc()185 SourceLocation getColonLoc() const { return ColonLoc; } setColonLoc(SourceLocation Loc)186 void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } getRParenLoc()187 SourceLocation getRParenLoc() const { return RParenLoc; } setRParenLoc(SourceLocation Loc)188 void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } 189 getSourceRange()190 SourceRange getSourceRange() const { 191 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 192 } classof(const Stmt * T)193 static bool classof(const Stmt *T) { 194 return T->getStmtClass() == CXXForRangeStmtClass; 195 } classof(const CXXForRangeStmt *)196 static bool classof(const CXXForRangeStmt *) { return true; } 197 198 // Iterators children()199 child_range children() { 200 return child_range(&SubExprs[0], &SubExprs[END]); 201 } 202 }; 203 204 205 } // end namespace clang 206 207 #endif 208