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/DeclarationName.h" 00018 #include "clang/AST/Expr.h" 00019 #include "clang/AST/NestedNameSpecifier.h" 00020 #include "clang/AST/Stmt.h" 00021 #include "llvm/Support/Compiler.h" 00022 00023 namespace clang { 00024 00025 class VarDecl; 00026 00027 /// CXXCatchStmt - This represents a C++ catch block. 00028 /// 00029 class CXXCatchStmt : public Stmt { 00030 SourceLocation CatchLoc; 00031 /// The exception-declaration of the type. 00032 VarDecl *ExceptionDecl; 00033 /// The handler block. 00034 Stmt *HandlerBlock; 00035 00036 public: 00037 CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock) 00038 : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl), 00039 HandlerBlock(handlerBlock) {} 00040 00041 CXXCatchStmt(EmptyShell Empty) 00042 : Stmt(CXXCatchStmtClass), ExceptionDecl(nullptr), HandlerBlock(nullptr) {} 00043 00044 SourceLocation getLocStart() const LLVM_READONLY { return CatchLoc; } 00045 SourceLocation getLocEnd() const LLVM_READONLY { 00046 return HandlerBlock->getLocEnd(); 00047 } 00048 00049 SourceLocation getCatchLoc() const { return CatchLoc; } 00050 VarDecl *getExceptionDecl() const { return ExceptionDecl; } 00051 QualType getCaughtType() const; 00052 Stmt *getHandlerBlock() const { return HandlerBlock; } 00053 00054 static bool classof(const Stmt *T) { 00055 return T->getStmtClass() == CXXCatchStmtClass; 00056 } 00057 00058 child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); } 00059 00060 friend class ASTStmtReader; 00061 }; 00062 00063 /// CXXTryStmt - A C++ try block, including all handlers. 00064 /// 00065 class CXXTryStmt : public Stmt { 00066 SourceLocation TryLoc; 00067 unsigned NumHandlers; 00068 00069 CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, ArrayRef<Stmt*> handlers); 00070 00071 CXXTryStmt(EmptyShell Empty, unsigned numHandlers) 00072 : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { } 00073 00074 Stmt const * const *getStmts() const { 00075 return reinterpret_cast<Stmt const * const*>(this + 1); 00076 } 00077 Stmt **getStmts() { 00078 return reinterpret_cast<Stmt **>(this + 1); 00079 } 00080 00081 public: 00082 static CXXTryStmt *Create(const ASTContext &C, SourceLocation tryLoc, 00083 Stmt *tryBlock, ArrayRef<Stmt*> handlers); 00084 00085 static CXXTryStmt *Create(const ASTContext &C, EmptyShell Empty, 00086 unsigned numHandlers); 00087 00088 SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); } 00089 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } 00090 00091 SourceLocation getTryLoc() const { return TryLoc; } 00092 SourceLocation getEndLoc() const { 00093 return getStmts()[NumHandlers]->getLocEnd(); 00094 } 00095 00096 CompoundStmt *getTryBlock() { 00097 return cast<CompoundStmt>(getStmts()[0]); 00098 } 00099 const CompoundStmt *getTryBlock() const { 00100 return cast<CompoundStmt>(getStmts()[0]); 00101 } 00102 00103 unsigned getNumHandlers() const { return NumHandlers; } 00104 CXXCatchStmt *getHandler(unsigned i) { 00105 return cast<CXXCatchStmt>(getStmts()[i + 1]); 00106 } 00107 const CXXCatchStmt *getHandler(unsigned i) const { 00108 return cast<CXXCatchStmt>(getStmts()[i + 1]); 00109 } 00110 00111 static bool classof(const Stmt *T) { 00112 return T->getStmtClass() == CXXTryStmtClass; 00113 } 00114 00115 child_range children() { 00116 return child_range(getStmts(), getStmts() + getNumHandlers() + 1); 00117 } 00118 00119 friend class ASTStmtReader; 00120 }; 00121 00122 /// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for 00123 /// statement, represented as 'for (range-declarator : range-expression)'. 00124 /// 00125 /// This is stored in a partially-desugared form to allow full semantic 00126 /// analysis of the constituent components. The original syntactic components 00127 /// can be extracted using getLoopVariable and getRangeInit. 00128 class CXXForRangeStmt : public Stmt { 00129 enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END }; 00130 // SubExprs[RANGE] is an expression or declstmt. 00131 // SubExprs[COND] and SubExprs[INC] are expressions. 00132 Stmt *SubExprs[END]; 00133 SourceLocation ForLoc; 00134 SourceLocation ColonLoc; 00135 SourceLocation RParenLoc; 00136 public: 00137 CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd, 00138 Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body, 00139 SourceLocation FL, SourceLocation CL, SourceLocation RPL); 00140 CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { } 00141 00142 00143 VarDecl *getLoopVariable(); 00144 Expr *getRangeInit(); 00145 00146 const VarDecl *getLoopVariable() const; 00147 const Expr *getRangeInit() const; 00148 00149 00150 DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); } 00151 DeclStmt *getBeginEndStmt() { 00152 return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); 00153 } 00154 Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); } 00155 Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); } 00156 DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); } 00157 Stmt *getBody() { return SubExprs[BODY]; } 00158 00159 const DeclStmt *getRangeStmt() const { 00160 return cast<DeclStmt>(SubExprs[RANGE]); 00161 } 00162 const DeclStmt *getBeginEndStmt() const { 00163 return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); 00164 } 00165 const Expr *getCond() const { 00166 return cast_or_null<Expr>(SubExprs[COND]); 00167 } 00168 const Expr *getInc() const { 00169 return cast_or_null<Expr>(SubExprs[INC]); 00170 } 00171 const DeclStmt *getLoopVarStmt() const { 00172 return cast<DeclStmt>(SubExprs[LOOPVAR]); 00173 } 00174 const Stmt *getBody() const { return SubExprs[BODY]; } 00175 00176 void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); } 00177 void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; } 00178 void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; } 00179 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } 00180 void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); } 00181 void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; } 00182 void setBody(Stmt *S) { SubExprs[BODY] = S; } 00183 00184 00185 SourceLocation getForLoc() const { return ForLoc; } 00186 void setForLoc(SourceLocation Loc) { ForLoc = Loc; } 00187 SourceLocation getColonLoc() const { return ColonLoc; } 00188 void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } 00189 SourceLocation getRParenLoc() const { return RParenLoc; } 00190 void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } 00191 00192 SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; } 00193 SourceLocation getLocEnd() const LLVM_READONLY { 00194 return SubExprs[BODY]->getLocEnd(); 00195 } 00196 00197 static bool classof(const Stmt *T) { 00198 return T->getStmtClass() == CXXForRangeStmtClass; 00199 } 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 SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; } 00279 SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();} 00280 00281 child_range children() { 00282 return child_range(&SubStmt, &SubStmt+1); 00283 } 00284 00285 static bool classof(const Stmt *T) { 00286 return T->getStmtClass() == MSDependentExistsStmtClass; 00287 } 00288 }; 00289 00290 } // end namespace clang 00291 00292 #endif