clang API Documentation
00001 //===--- StmtCXX.h - Classes for representing C++ statements ----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the C++ statement AST node classes. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CLANG_AST_STMTCXX_H 00015 #define LLVM_CLANG_AST_STMTCXX_H 00016 00017 #include "clang/AST/Stmt.h" 00018 #include "llvm/Support/Compiler.h" 00019 00020 namespace clang { 00021 00022 class VarDecl; 00023 00024 /// CXXCatchStmt - This represents a C++ catch block. 00025 /// 00026 class CXXCatchStmt : public Stmt { 00027 SourceLocation CatchLoc; 00028 /// The exception-declaration of the type. 00029 VarDecl *ExceptionDecl; 00030 /// The handler block. 00031 Stmt *HandlerBlock; 00032 00033 public: 00034 CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock) 00035 : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl), 00036 HandlerBlock(handlerBlock) {} 00037 00038 CXXCatchStmt(EmptyShell Empty) 00039 : Stmt(CXXCatchStmtClass), ExceptionDecl(0), HandlerBlock(0) {} 00040 00041 SourceRange getSourceRange() const LLVM_READONLY { 00042 return SourceRange(CatchLoc, HandlerBlock->getLocEnd()); 00043 } 00044 00045 SourceLocation getCatchLoc() const { return CatchLoc; } 00046 VarDecl *getExceptionDecl() const { return ExceptionDecl; } 00047 QualType getCaughtType() const; 00048 Stmt *getHandlerBlock() const { return HandlerBlock; } 00049 00050 static bool classof(const Stmt *T) { 00051 return T->getStmtClass() == CXXCatchStmtClass; 00052 } 00053 static bool classof(const CXXCatchStmt *) { return true; } 00054 00055 child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); } 00056 00057 friend class ASTStmtReader; 00058 }; 00059 00060 /// CXXTryStmt - A C++ try block, including all handlers. 00061 /// 00062 class CXXTryStmt : public Stmt { 00063 SourceLocation TryLoc; 00064 unsigned NumHandlers; 00065 00066 CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, Stmt **handlers, 00067 unsigned numHandlers); 00068 00069 CXXTryStmt(EmptyShell Empty, unsigned numHandlers) 00070 : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { } 00071 00072 Stmt const * const *getStmts() const { 00073 return reinterpret_cast<Stmt const * const*>(this + 1); 00074 } 00075 Stmt **getStmts() { 00076 return reinterpret_cast<Stmt **>(this + 1); 00077 } 00078 00079 public: 00080 static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc, 00081 Stmt *tryBlock, Stmt **handlers, 00082 unsigned numHandlers); 00083 00084 static CXXTryStmt *Create(ASTContext &C, EmptyShell Empty, 00085 unsigned numHandlers); 00086 00087 SourceRange getSourceRange() const LLVM_READONLY { 00088 return SourceRange(getTryLoc(), getEndLoc()); 00089 } 00090 00091 SourceLocation getTryLoc() const { return TryLoc; } 00092 SourceLocation getEndLoc() const { 00093 return getStmts()[NumHandlers]->getLocEnd(); 00094 } 00095 00096 CompoundStmt *getTryBlock() { 00097 return llvm::cast<CompoundStmt>(getStmts()[0]); 00098 } 00099 const CompoundStmt *getTryBlock() const { 00100 return llvm::cast<CompoundStmt>(getStmts()[0]); 00101 } 00102 00103 unsigned getNumHandlers() const { return NumHandlers; } 00104 CXXCatchStmt *getHandler(unsigned i) { 00105 return llvm::cast<CXXCatchStmt>(getStmts()[i + 1]); 00106 } 00107 const CXXCatchStmt *getHandler(unsigned i) const { 00108 return llvm::cast<CXXCatchStmt>(getStmts()[i + 1]); 00109 } 00110 00111 static bool classof(const Stmt *T) { 00112 return T->getStmtClass() == CXXTryStmtClass; 00113 } 00114 static bool classof(const CXXTryStmt *) { return true; } 00115 00116 child_range children() { 00117 return child_range(getStmts(), getStmts() + getNumHandlers() + 1); 00118 } 00119 00120 friend class ASTStmtReader; 00121 }; 00122 00123 /// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for 00124 /// statement, represented as 'for (range-declarator : range-expression)'. 00125 /// 00126 /// This is stored in a partially-desugared form to allow full semantic 00127 /// analysis of the constituent components. The original syntactic components 00128 /// can be extracted using getLoopVariable and getRangeInit. 00129 class CXXForRangeStmt : public Stmt { 00130 enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END }; 00131 // SubExprs[RANGE] is an expression or declstmt. 00132 // SubExprs[COND] and SubExprs[INC] are expressions. 00133 Stmt *SubExprs[END]; 00134 SourceLocation ForLoc; 00135 SourceLocation ColonLoc; 00136 SourceLocation RParenLoc; 00137 public: 00138 CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd, 00139 Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body, 00140 SourceLocation FL, SourceLocation CL, SourceLocation RPL); 00141 CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { } 00142 00143 00144 VarDecl *getLoopVariable(); 00145 Expr *getRangeInit(); 00146 00147 const VarDecl *getLoopVariable() const; 00148 const Expr *getRangeInit() const; 00149 00150 00151 DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); } 00152 DeclStmt *getBeginEndStmt() { 00153 return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); 00154 } 00155 Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); } 00156 Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); } 00157 DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); } 00158 Stmt *getBody() { return SubExprs[BODY]; } 00159 00160 const DeclStmt *getRangeStmt() const { 00161 return cast<DeclStmt>(SubExprs[RANGE]); 00162 } 00163 const DeclStmt *getBeginEndStmt() const { 00164 return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); 00165 } 00166 const Expr *getCond() const { 00167 return cast_or_null<Expr>(SubExprs[COND]); 00168 } 00169 const Expr *getInc() const { 00170 return cast_or_null<Expr>(SubExprs[INC]); 00171 } 00172 const DeclStmt *getLoopVarStmt() const { 00173 return cast<DeclStmt>(SubExprs[LOOPVAR]); 00174 } 00175 const Stmt *getBody() const { return SubExprs[BODY]; } 00176 00177 void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); } 00178 void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; } 00179 void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; } 00180 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } 00181 void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); } 00182 void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; } 00183 void setBody(Stmt *S) { SubExprs[BODY] = S; } 00184 00185 00186 SourceLocation getForLoc() const { return ForLoc; } 00187 void setForLoc(SourceLocation Loc) { ForLoc = Loc; } 00188 SourceLocation getColonLoc() const { return ColonLoc; } 00189 void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } 00190 SourceLocation getRParenLoc() const { return RParenLoc; } 00191 void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } 00192 00193 SourceRange getSourceRange() const LLVM_READONLY { 00194 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 00195 } 00196 static bool classof(const Stmt *T) { 00197 return T->getStmtClass() == CXXForRangeStmtClass; 00198 } 00199 static bool classof(const CXXForRangeStmt *) { return true; } 00200 00201 // Iterators 00202 child_range children() { 00203 return child_range(&SubExprs[0], &SubExprs[END]); 00204 } 00205 }; 00206 00207 /// \brief Representation of a Microsoft __if_exists or __if_not_exists 00208 /// statement with a dependent name. 00209 /// 00210 /// The __if_exists statement can be used to include a sequence of statements 00211 /// in the program only when a particular dependent name does not exist. For 00212 /// example: 00213 /// 00214 /// \code 00215 /// template<typename T> 00216 /// void call_foo(T &t) { 00217 /// __if_exists (T::foo) { 00218 /// t.foo(); // okay: only called when T::foo exists. 00219 /// } 00220 /// } 00221 /// \endcode 00222 /// 00223 /// Similarly, the __if_not_exists statement can be used to include the 00224 /// statements when a particular name does not exist. 00225 /// 00226 /// Note that this statement only captures __if_exists and __if_not_exists 00227 /// statements whose name is dependent. All non-dependent cases are handled 00228 /// directly in the parser, so that they don't introduce a new scope. Clang 00229 /// introduces scopes in the dependent case to keep names inside the compound 00230 /// statement from leaking out into the surround statements, which would 00231 /// compromise the template instantiation model. This behavior differs from 00232 /// Visual C++ (which never introduces a scope), but is a fairly reasonable 00233 /// approximation of the VC++ behavior. 00234 class MSDependentExistsStmt : public Stmt { 00235 SourceLocation KeywordLoc; 00236 bool IsIfExists; 00237 NestedNameSpecifierLoc QualifierLoc; 00238 DeclarationNameInfo NameInfo; 00239 Stmt *SubStmt; 00240 00241 friend class ASTReader; 00242 friend class ASTStmtReader; 00243 00244 public: 00245 MSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, 00246 NestedNameSpecifierLoc QualifierLoc, 00247 DeclarationNameInfo NameInfo, 00248 CompoundStmt *SubStmt) 00249 : Stmt(MSDependentExistsStmtClass), 00250 KeywordLoc(KeywordLoc), IsIfExists(IsIfExists), 00251 QualifierLoc(QualifierLoc), NameInfo(NameInfo), 00252 SubStmt(reinterpret_cast<Stmt *>(SubStmt)) { } 00253 00254 /// \brief Retrieve the location of the __if_exists or __if_not_exists 00255 /// keyword. 00256 SourceLocation getKeywordLoc() const { return KeywordLoc; } 00257 00258 /// \brief Determine whether this is an __if_exists statement. 00259 bool isIfExists() const { return IsIfExists; } 00260 00261 /// \brief Determine whether this is an __if_exists statement. 00262 bool isIfNotExists() const { return !IsIfExists; } 00263 00264 /// \brief Retrieve the nested-name-specifier that qualifies this name, if 00265 /// any. 00266 NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } 00267 00268 /// \brief Retrieve the name of the entity we're testing for, along with 00269 /// location information 00270 DeclarationNameInfo getNameInfo() const { return NameInfo; } 00271 00272 /// \brief Retrieve the compound statement that will be included in the 00273 /// program only if the existence of the symbol matches the initial keyword. 00274 CompoundStmt *getSubStmt() const { 00275 return reinterpret_cast<CompoundStmt *>(SubStmt); 00276 } 00277 00278 SourceRange getSourceRange() const LLVM_READONLY { 00279 return SourceRange(KeywordLoc, SubStmt->getLocEnd()); 00280 } 00281 00282 child_range children() { 00283 return child_range(&SubStmt, &SubStmt+1); 00284 } 00285 00286 static bool classof(const Stmt *T) { 00287 return T->getStmtClass() == MSDependentExistsStmtClass; 00288 } 00289 00290 static bool classof(MSDependentExistsStmt *) { return true; } 00291 }; 00292 00293 } // end namespace clang 00294 00295 #endif