1193326Sed//===--- StmtCXX.h - Classes for representing C++ statements ----*- C++ -*-===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file defines the C++ statement AST node classes. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#ifndef LLVM_CLANG_AST_STMTCXX_H 15193326Sed#define LLVM_CLANG_AST_STMTCXX_H 16193326Sed 17249423Sdim#include "clang/AST/DeclarationName.h" 18249423Sdim#include "clang/AST/Expr.h" 19249423Sdim#include "clang/AST/NestedNameSpecifier.h" 20193326Sed#include "clang/AST/Stmt.h" 21234353Sdim#include "llvm/Support/Compiler.h" 22193326Sed 23193326Sednamespace clang { 24193326Sed 25193326Sedclass VarDecl; 26193326Sed 27193326Sed/// CXXCatchStmt - This represents a C++ catch block. 28193326Sed/// 29193326Sedclass CXXCatchStmt : public Stmt { 30193326Sed SourceLocation CatchLoc; 31193326Sed /// The exception-declaration of the type. 32193326Sed VarDecl *ExceptionDecl; 33193326Sed /// The handler block. 34193326Sed Stmt *HandlerBlock; 35193326Sed 36193326Sedpublic: 37193326Sed CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock) 38193326Sed : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl), 39193326Sed HandlerBlock(handlerBlock) {} 40193326Sed 41212904Sdim CXXCatchStmt(EmptyShell Empty) 42212904Sdim : Stmt(CXXCatchStmtClass), ExceptionDecl(0), HandlerBlock(0) {} 43212904Sdim 44249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return CatchLoc; } 45249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { 46249423Sdim return HandlerBlock->getLocEnd(); 47193326Sed } 48193326Sed 49193326Sed SourceLocation getCatchLoc() const { return CatchLoc; } 50199990Srdivacky VarDecl *getExceptionDecl() const { return ExceptionDecl; } 51199990Srdivacky QualType getCaughtType() const; 52199990Srdivacky Stmt *getHandlerBlock() const { return HandlerBlock; } 53193326Sed 54193326Sed static bool classof(const Stmt *T) { 55193326Sed return T->getStmtClass() == CXXCatchStmtClass; 56193326Sed } 57193326Sed 58218893Sdim child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); } 59212904Sdim 60212904Sdim friend class ASTStmtReader; 61193326Sed}; 62193326Sed 63193326Sed/// CXXTryStmt - A C++ try block, including all handlers. 64193326Sed/// 65193326Sedclass CXXTryStmt : public Stmt { 66193326Sed SourceLocation TryLoc; 67203955Srdivacky unsigned NumHandlers; 68193326Sed 69249423Sdim CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, ArrayRef<Stmt*> handlers); 70203955Srdivacky 71212904Sdim CXXTryStmt(EmptyShell Empty, unsigned numHandlers) 72212904Sdim : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { } 73212904Sdim 74212904Sdim Stmt const * const *getStmts() const { 75212904Sdim return reinterpret_cast<Stmt const * const*>(this + 1); 76212904Sdim } 77212904Sdim Stmt **getStmts() { 78212904Sdim return reinterpret_cast<Stmt **>(this + 1); 79212904Sdim } 80212904Sdim 81193326Sedpublic: 82203955Srdivacky static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc, 83249423Sdim Stmt *tryBlock, ArrayRef<Stmt*> handlers); 84193326Sed 85212904Sdim static CXXTryStmt *Create(ASTContext &C, EmptyShell Empty, 86212904Sdim unsigned numHandlers); 87212904Sdim 88249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); } 89249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } 90193326Sed 91193326Sed SourceLocation getTryLoc() const { return TryLoc; } 92203955Srdivacky SourceLocation getEndLoc() const { 93212904Sdim return getStmts()[NumHandlers]->getLocEnd(); 94203955Srdivacky } 95193326Sed 96203955Srdivacky CompoundStmt *getTryBlock() { 97249423Sdim return cast<CompoundStmt>(getStmts()[0]); 98203955Srdivacky } 99193326Sed const CompoundStmt *getTryBlock() const { 100249423Sdim return cast<CompoundStmt>(getStmts()[0]); 101193326Sed } 102193326Sed 103203955Srdivacky unsigned getNumHandlers() const { return NumHandlers; } 104193326Sed CXXCatchStmt *getHandler(unsigned i) { 105249423Sdim return cast<CXXCatchStmt>(getStmts()[i + 1]); 106193326Sed } 107193326Sed const CXXCatchStmt *getHandler(unsigned i) const { 108249423Sdim return cast<CXXCatchStmt>(getStmts()[i + 1]); 109193326Sed } 110193326Sed 111193326Sed static bool classof(const Stmt *T) { 112193326Sed return T->getStmtClass() == CXXTryStmtClass; 113193326Sed } 114193326Sed 115218893Sdim child_range children() { 116218893Sdim return child_range(getStmts(), getStmts() + getNumHandlers() + 1); 117218893Sdim } 118212904Sdim 119212904Sdim friend class ASTStmtReader; 120193326Sed}; 121193326Sed 122221345Sdim/// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for 123221345Sdim/// statement, represented as 'for (range-declarator : range-expression)'. 124221345Sdim/// 125221345Sdim/// This is stored in a partially-desugared form to allow full semantic 126221345Sdim/// analysis of the constituent components. The original syntactic components 127221345Sdim/// can be extracted using getLoopVariable and getRangeInit. 128221345Sdimclass CXXForRangeStmt : public Stmt { 129221345Sdim enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END }; 130221345Sdim // SubExprs[RANGE] is an expression or declstmt. 131221345Sdim // SubExprs[COND] and SubExprs[INC] are expressions. 132221345Sdim Stmt *SubExprs[END]; 133221345Sdim SourceLocation ForLoc; 134221345Sdim SourceLocation ColonLoc; 135221345Sdim SourceLocation RParenLoc; 136221345Sdimpublic: 137221345Sdim CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd, 138221345Sdim Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body, 139221345Sdim SourceLocation FL, SourceLocation CL, SourceLocation RPL); 140221345Sdim CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { } 141193326Sed 142221345Sdim 143221345Sdim VarDecl *getLoopVariable(); 144221345Sdim Expr *getRangeInit(); 145221345Sdim 146221345Sdim const VarDecl *getLoopVariable() const; 147221345Sdim const Expr *getRangeInit() const; 148221345Sdim 149221345Sdim 150221345Sdim DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); } 151234353Sdim DeclStmt *getBeginEndStmt() { 152234353Sdim return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); 153234353Sdim } 154221345Sdim Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); } 155221345Sdim Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); } 156221345Sdim DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); } 157221345Sdim Stmt *getBody() { return SubExprs[BODY]; } 158221345Sdim 159221345Sdim const DeclStmt *getRangeStmt() const { 160221345Sdim return cast<DeclStmt>(SubExprs[RANGE]); 161221345Sdim } 162221345Sdim const DeclStmt *getBeginEndStmt() const { 163221345Sdim return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); 164221345Sdim } 165221345Sdim const Expr *getCond() const { 166221345Sdim return cast_or_null<Expr>(SubExprs[COND]); 167221345Sdim } 168221345Sdim const Expr *getInc() const { 169221345Sdim return cast_or_null<Expr>(SubExprs[INC]); 170221345Sdim } 171221345Sdim const DeclStmt *getLoopVarStmt() const { 172221345Sdim return cast<DeclStmt>(SubExprs[LOOPVAR]); 173221345Sdim } 174221345Sdim const Stmt *getBody() const { return SubExprs[BODY]; } 175221345Sdim 176221345Sdim void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); } 177221345Sdim void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; } 178221345Sdim void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; } 179221345Sdim void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } 180221345Sdim void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); } 181221345Sdim void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; } 182221345Sdim void setBody(Stmt *S) { SubExprs[BODY] = S; } 183221345Sdim 184221345Sdim 185221345Sdim SourceLocation getForLoc() const { return ForLoc; } 186221345Sdim void setForLoc(SourceLocation Loc) { ForLoc = Loc; } 187221345Sdim SourceLocation getColonLoc() const { return ColonLoc; } 188221345Sdim void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } 189221345Sdim SourceLocation getRParenLoc() const { return RParenLoc; } 190221345Sdim void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } 191221345Sdim 192249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; } 193249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { 194249423Sdim return SubExprs[BODY]->getLocEnd(); 195221345Sdim } 196249423Sdim 197221345Sdim static bool classof(const Stmt *T) { 198221345Sdim return T->getStmtClass() == CXXForRangeStmtClass; 199221345Sdim } 200221345Sdim 201221345Sdim // Iterators 202221345Sdim child_range children() { 203221345Sdim return child_range(&SubExprs[0], &SubExprs[END]); 204221345Sdim } 205221345Sdim}; 206221345Sdim 207234353Sdim/// \brief Representation of a Microsoft __if_exists or __if_not_exists 208234353Sdim/// statement with a dependent name. 209234353Sdim/// 210234353Sdim/// The __if_exists statement can be used to include a sequence of statements 211234353Sdim/// in the program only when a particular dependent name does not exist. For 212234353Sdim/// example: 213234353Sdim/// 214234353Sdim/// \code 215234353Sdim/// template<typename T> 216234353Sdim/// void call_foo(T &t) { 217234353Sdim/// __if_exists (T::foo) { 218234353Sdim/// t.foo(); // okay: only called when T::foo exists. 219234353Sdim/// } 220234353Sdim/// } 221234353Sdim/// \endcode 222234353Sdim/// 223234353Sdim/// Similarly, the __if_not_exists statement can be used to include the 224234353Sdim/// statements when a particular name does not exist. 225234353Sdim/// 226234353Sdim/// Note that this statement only captures __if_exists and __if_not_exists 227234353Sdim/// statements whose name is dependent. All non-dependent cases are handled 228234353Sdim/// directly in the parser, so that they don't introduce a new scope. Clang 229234353Sdim/// introduces scopes in the dependent case to keep names inside the compound 230234353Sdim/// statement from leaking out into the surround statements, which would 231234353Sdim/// compromise the template instantiation model. This behavior differs from 232234353Sdim/// Visual C++ (which never introduces a scope), but is a fairly reasonable 233234353Sdim/// approximation of the VC++ behavior. 234234353Sdimclass MSDependentExistsStmt : public Stmt { 235234353Sdim SourceLocation KeywordLoc; 236234353Sdim bool IsIfExists; 237234353Sdim NestedNameSpecifierLoc QualifierLoc; 238234353Sdim DeclarationNameInfo NameInfo; 239234353Sdim Stmt *SubStmt; 240221345Sdim 241234353Sdim friend class ASTReader; 242234353Sdim friend class ASTStmtReader; 243234353Sdim 244234353Sdimpublic: 245234353Sdim MSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, 246234353Sdim NestedNameSpecifierLoc QualifierLoc, 247234353Sdim DeclarationNameInfo NameInfo, 248234353Sdim CompoundStmt *SubStmt) 249234353Sdim : Stmt(MSDependentExistsStmtClass), 250234353Sdim KeywordLoc(KeywordLoc), IsIfExists(IsIfExists), 251234353Sdim QualifierLoc(QualifierLoc), NameInfo(NameInfo), 252234353Sdim SubStmt(reinterpret_cast<Stmt *>(SubStmt)) { } 253234353Sdim 254234353Sdim /// \brief Retrieve the location of the __if_exists or __if_not_exists 255234353Sdim /// keyword. 256234353Sdim SourceLocation getKeywordLoc() const { return KeywordLoc; } 257234353Sdim 258234353Sdim /// \brief Determine whether this is an __if_exists statement. 259234353Sdim bool isIfExists() const { return IsIfExists; } 260234353Sdim 261234353Sdim /// \brief Determine whether this is an __if_exists statement. 262234353Sdim bool isIfNotExists() const { return !IsIfExists; } 263234353Sdim 264234353Sdim /// \brief Retrieve the nested-name-specifier that qualifies this name, if 265234353Sdim /// any. 266234353Sdim NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } 267234353Sdim 268234353Sdim /// \brief Retrieve the name of the entity we're testing for, along with 269234353Sdim /// location information 270234353Sdim DeclarationNameInfo getNameInfo() const { return NameInfo; } 271234353Sdim 272234353Sdim /// \brief Retrieve the compound statement that will be included in the 273234353Sdim /// program only if the existence of the symbol matches the initial keyword. 274234353Sdim CompoundStmt *getSubStmt() const { 275234353Sdim return reinterpret_cast<CompoundStmt *>(SubStmt); 276234353Sdim } 277234353Sdim 278249423Sdim SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; } 279249423Sdim SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();} 280234353Sdim 281234353Sdim child_range children() { 282234353Sdim return child_range(&SubStmt, &SubStmt+1); 283234353Sdim } 284234353Sdim 285234353Sdim static bool classof(const Stmt *T) { 286234353Sdim return T->getStmtClass() == MSDependentExistsStmtClass; 287234353Sdim } 288234353Sdim}; 289234353Sdim 290193326Sed} // end namespace clang 291193326Sed 292193326Sed#endif 293