StmtCXX.h revision 263508
1219820Sjeff//===--- StmtCXX.h - Classes for representing C++ statements ----*- C++ -*-===// 2219820Sjeff// 3219820Sjeff// The LLVM Compiler Infrastructure 4219820Sjeff// 5219820Sjeff// This file is distributed under the University of Illinois Open Source 6219820Sjeff// License. See LICENSE.TXT for details. 7219820Sjeff// 8219820Sjeff//===----------------------------------------------------------------------===// 9219820Sjeff// 10219820Sjeff// This file defines the C++ statement AST node classes. 11219820Sjeff// 12219820Sjeff//===----------------------------------------------------------------------===// 13219820Sjeff 14219820Sjeff#ifndef LLVM_CLANG_AST_STMTCXX_H 15219820Sjeff#define LLVM_CLANG_AST_STMTCXX_H 16219820Sjeff 17219820Sjeff#include "clang/AST/DeclarationName.h" 18219820Sjeff#include "clang/AST/Expr.h" 19219820Sjeff#include "clang/AST/NestedNameSpecifier.h" 20219820Sjeff#include "clang/AST/Stmt.h" 21219820Sjeff#include "llvm/Support/Compiler.h" 22219820Sjeff 23219820Sjeffnamespace clang { 24219820Sjeff 25219820Sjeffclass VarDecl; 26219820Sjeff 27219820Sjeff/// CXXCatchStmt - This represents a C++ catch block. 28219820Sjeff/// 29219820Sjeffclass CXXCatchStmt : public Stmt { 30219820Sjeff SourceLocation CatchLoc; 31219820Sjeff /// The exception-declaration of the type. 32219820Sjeff VarDecl *ExceptionDecl; 33219820Sjeff /// The handler block. 34219820Sjeff Stmt *HandlerBlock; 35219820Sjeff 36219820Sjeffpublic: 37219820Sjeff CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock) 38219820Sjeff : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl), 39219820Sjeff HandlerBlock(handlerBlock) {} 40219820Sjeff 41219820Sjeff CXXCatchStmt(EmptyShell Empty) 42219820Sjeff : Stmt(CXXCatchStmtClass), ExceptionDecl(0), HandlerBlock(0) {} 43219820Sjeff 44219820Sjeff SourceLocation getLocStart() const LLVM_READONLY { return CatchLoc; } 45219820Sjeff SourceLocation getLocEnd() const LLVM_READONLY { 46271127Shselasky return HandlerBlock->getLocEnd(); 47219820Sjeff } 48219820Sjeff 49219820Sjeff SourceLocation getCatchLoc() const { return CatchLoc; } 50219820Sjeff VarDecl *getExceptionDecl() const { return ExceptionDecl; } 51219820Sjeff QualType getCaughtType() const; 52219820Sjeff Stmt *getHandlerBlock() const { return HandlerBlock; } 53219820Sjeff 54219820Sjeff static bool classof(const Stmt *T) { 55219820Sjeff return T->getStmtClass() == CXXCatchStmtClass; 56219820Sjeff } 57219820Sjeff 58219820Sjeff child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); } 59219820Sjeff 60219820Sjeff friend class ASTStmtReader; 61219820Sjeff}; 62219820Sjeff 63219820Sjeff/// CXXTryStmt - A C++ try block, including all handlers. 64219820Sjeff/// 65219820Sjeffclass CXXTryStmt : public Stmt { 66219820Sjeff SourceLocation TryLoc; 67219820Sjeff unsigned NumHandlers; 68219820Sjeff 69219820Sjeff CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, ArrayRef<Stmt*> handlers); 70219820Sjeff 71219820Sjeff CXXTryStmt(EmptyShell Empty, unsigned numHandlers) 72219820Sjeff : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { } 73219820Sjeff 74219820Sjeff Stmt const * const *getStmts() const { 75219820Sjeff return reinterpret_cast<Stmt const * const*>(this + 1); 76219820Sjeff } 77219820Sjeff Stmt **getStmts() { 78219820Sjeff return reinterpret_cast<Stmt **>(this + 1); 79219820Sjeff } 80219820Sjeff 81219820Sjeffpublic: 82219820Sjeff static CXXTryStmt *Create(const ASTContext &C, SourceLocation tryLoc, 83219820Sjeff Stmt *tryBlock, ArrayRef<Stmt*> handlers); 84219820Sjeff 85219820Sjeff static CXXTryStmt *Create(const ASTContext &C, EmptyShell Empty, 86219820Sjeff unsigned numHandlers); 87219820Sjeff 88219820Sjeff SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); } 89219820Sjeff SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } 90219820Sjeff 91219820Sjeff SourceLocation getTryLoc() const { return TryLoc; } 92219820Sjeff SourceLocation getEndLoc() const { 93219820Sjeff return getStmts()[NumHandlers]->getLocEnd(); 94219820Sjeff } 95219820Sjeff 96219820Sjeff CompoundStmt *getTryBlock() { 97219820Sjeff return cast<CompoundStmt>(getStmts()[0]); 98219820Sjeff } 99219820Sjeff const CompoundStmt *getTryBlock() const { 100219820Sjeff return cast<CompoundStmt>(getStmts()[0]); 101219820Sjeff } 102219820Sjeff 103219820Sjeff unsigned getNumHandlers() const { return NumHandlers; } 104219820Sjeff CXXCatchStmt *getHandler(unsigned i) { 105219820Sjeff return cast<CXXCatchStmt>(getStmts()[i + 1]); 106219820Sjeff } 107219820Sjeff const CXXCatchStmt *getHandler(unsigned i) const { 108219820Sjeff return cast<CXXCatchStmt>(getStmts()[i + 1]); 109219820Sjeff } 110219820Sjeff 111219820Sjeff static bool classof(const Stmt *T) { 112219820Sjeff return T->getStmtClass() == CXXTryStmtClass; 113219820Sjeff } 114219820Sjeff 115219820Sjeff child_range children() { 116219820Sjeff return child_range(getStmts(), getStmts() + getNumHandlers() + 1); 117219820Sjeff } 118219820Sjeff 119219820Sjeff friend class ASTStmtReader; 120219820Sjeff}; 121219820Sjeff 122219820Sjeff/// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for 123219820Sjeff/// statement, represented as 'for (range-declarator : range-expression)'. 124219820Sjeff/// 125219820Sjeff/// This is stored in a partially-desugared form to allow full semantic 126219820Sjeff/// analysis of the constituent components. The original syntactic components 127219820Sjeff/// can be extracted using getLoopVariable and getRangeInit. 128219820Sjeffclass CXXForRangeStmt : public Stmt { 129219820Sjeff enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END }; 130219820Sjeff // SubExprs[RANGE] is an expression or declstmt. 131219820Sjeff // SubExprs[COND] and SubExprs[INC] are expressions. 132219820Sjeff Stmt *SubExprs[END]; 133219820Sjeff SourceLocation ForLoc; 134219820Sjeff SourceLocation ColonLoc; 135219820Sjeff SourceLocation RParenLoc; 136219820Sjeffpublic: 137219820Sjeff CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd, 138219820Sjeff Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body, 139219820Sjeff SourceLocation FL, SourceLocation CL, SourceLocation RPL); 140219820Sjeff CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { } 141219820Sjeff 142219820Sjeff 143219820Sjeff VarDecl *getLoopVariable(); 144219820Sjeff Expr *getRangeInit(); 145219820Sjeff 146219820Sjeff const VarDecl *getLoopVariable() const; 147219820Sjeff const Expr *getRangeInit() const; 148219820Sjeff 149219820Sjeff 150219820Sjeff DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); } 151219820Sjeff DeclStmt *getBeginEndStmt() { 152219820Sjeff return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); 153219820Sjeff } 154219820Sjeff Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); } 155219820Sjeff Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); } 156219820Sjeff DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); } 157219820Sjeff Stmt *getBody() { return SubExprs[BODY]; } 158219820Sjeff 159219820Sjeff const DeclStmt *getRangeStmt() const { 160219820Sjeff return cast<DeclStmt>(SubExprs[RANGE]); 161219820Sjeff } 162219820Sjeff const DeclStmt *getBeginEndStmt() const { 163219820Sjeff return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); 164219820Sjeff } 165219820Sjeff const Expr *getCond() const { 166219820Sjeff return cast_or_null<Expr>(SubExprs[COND]); 167219820Sjeff } 168219820Sjeff const Expr *getInc() const { 169219820Sjeff return cast_or_null<Expr>(SubExprs[INC]); 170219820Sjeff } 171219820Sjeff const DeclStmt *getLoopVarStmt() const { 172219820Sjeff return cast<DeclStmt>(SubExprs[LOOPVAR]); 173219820Sjeff } 174219820Sjeff const Stmt *getBody() const { return SubExprs[BODY]; } 175219820Sjeff 176219820Sjeff void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); } 177219820Sjeff void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; } 178219820Sjeff void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; } 179219820Sjeff void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } 180219820Sjeff void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); } 181219820Sjeff void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; } 182219820Sjeff void setBody(Stmt *S) { SubExprs[BODY] = S; } 183219820Sjeff 184219820Sjeff 185219820Sjeff SourceLocation getForLoc() const { return ForLoc; } 186219820Sjeff void setForLoc(SourceLocation Loc) { ForLoc = Loc; } 187219820Sjeff SourceLocation getColonLoc() const { return ColonLoc; } 188219820Sjeff void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } 189219820Sjeff SourceLocation getRParenLoc() const { return RParenLoc; } 190219820Sjeff void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } 191219820Sjeff 192219820Sjeff SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; } 193237263Snp SourceLocation getLocEnd() const LLVM_READONLY { 194219820Sjeff return SubExprs[BODY]->getLocEnd(); 195219820Sjeff } 196219820Sjeff 197219820Sjeff static bool classof(const Stmt *T) { 198219820Sjeff return T->getStmtClass() == CXXForRangeStmtClass; 199219820Sjeff } 200219820Sjeff 201219820Sjeff // Iterators 202219820Sjeff child_range children() { 203219820Sjeff return child_range(&SubExprs[0], &SubExprs[END]); 204219820Sjeff } 205219820Sjeff}; 206219820Sjeff 207219820Sjeff/// \brief Representation of a Microsoft __if_exists or __if_not_exists 208219820Sjeff/// statement with a dependent name. 209219820Sjeff/// 210237263Snp/// The __if_exists statement can be used to include a sequence of statements 211219820Sjeff/// in the program only when a particular dependent name does not exist. For 212219820Sjeff/// example: 213219820Sjeff/// 214219820Sjeff/// \code 215219820Sjeff/// template<typename T> 216219820Sjeff/// void call_foo(T &t) { 217219820Sjeff/// __if_exists (T::foo) { 218219820Sjeff/// t.foo(); // okay: only called when T::foo exists. 219219820Sjeff/// } 220219820Sjeff/// } 221219820Sjeff/// \endcode 222219820Sjeff/// 223219820Sjeff/// Similarly, the __if_not_exists statement can be used to include the 224219820Sjeff/// statements when a particular name does not exist. 225219820Sjeff/// 226219820Sjeff/// Note that this statement only captures __if_exists and __if_not_exists 227219820Sjeff/// statements whose name is dependent. All non-dependent cases are handled 228219820Sjeff/// directly in the parser, so that they don't introduce a new scope. Clang 229219820Sjeff/// introduces scopes in the dependent case to keep names inside the compound 230219820Sjeff/// statement from leaking out into the surround statements, which would 231219820Sjeff/// compromise the template instantiation model. This behavior differs from 232219820Sjeff/// Visual C++ (which never introduces a scope), but is a fairly reasonable 233219820Sjeff/// approximation of the VC++ behavior. 234219820Sjeffclass MSDependentExistsStmt : public Stmt { 235219820Sjeff SourceLocation KeywordLoc; 236219820Sjeff bool IsIfExists; 237219820Sjeff NestedNameSpecifierLoc QualifierLoc; 238219820Sjeff DeclarationNameInfo NameInfo; 239219820Sjeff Stmt *SubStmt; 240219820Sjeff 241219820Sjeff friend class ASTReader; 242219820Sjeff friend class ASTStmtReader; 243219820Sjeff 244219820Sjeffpublic: 245219820Sjeff MSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, 246219820Sjeff NestedNameSpecifierLoc QualifierLoc, 247219820Sjeff DeclarationNameInfo NameInfo, 248219820Sjeff CompoundStmt *SubStmt) 249219820Sjeff : Stmt(MSDependentExistsStmtClass), 250219820Sjeff KeywordLoc(KeywordLoc), IsIfExists(IsIfExists), 251219820Sjeff QualifierLoc(QualifierLoc), NameInfo(NameInfo), 252219820Sjeff SubStmt(reinterpret_cast<Stmt *>(SubStmt)) { } 253219820Sjeff 254219820Sjeff /// \brief Retrieve the location of the __if_exists or __if_not_exists 255219820Sjeff /// keyword. 256219820Sjeff SourceLocation getKeywordLoc() const { return KeywordLoc; } 257219820Sjeff 258219820Sjeff /// \brief Determine whether this is an __if_exists statement. 259219820Sjeff bool isIfExists() const { return IsIfExists; } 260219820Sjeff 261219820Sjeff /// \brief Determine whether this is an __if_exists statement. 262219820Sjeff bool isIfNotExists() const { return !IsIfExists; } 263219820Sjeff 264219820Sjeff /// \brief Retrieve the nested-name-specifier that qualifies this name, if 265219820Sjeff /// any. 266219820Sjeff NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } 267219820Sjeff 268219820Sjeff /// \brief Retrieve the name of the entity we're testing for, along with 269219820Sjeff /// location information 270219820Sjeff DeclarationNameInfo getNameInfo() const { return NameInfo; } 271219820Sjeff 272219820Sjeff /// \brief Retrieve the compound statement that will be included in the 273219820Sjeff /// program only if the existence of the symbol matches the initial keyword. 274219820Sjeff CompoundStmt *getSubStmt() const { 275219820Sjeff return reinterpret_cast<CompoundStmt *>(SubStmt); 276219820Sjeff } 277219820Sjeff 278219820Sjeff SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; } 279219820Sjeff SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();} 280219820Sjeff 281219820Sjeff child_range children() { 282219820Sjeff return child_range(&SubStmt, &SubStmt+1); 283219820Sjeff } 284219820Sjeff 285219820Sjeff static bool classof(const Stmt *T) { 286219820Sjeff return T->getStmtClass() == MSDependentExistsStmtClass; 287219820Sjeff } 288219820Sjeff}; 289219820Sjeff 290219820Sjeff} // end namespace clang 291219820Sjeff 292219820Sjeff#endif 293219820Sjeff